How to Use Go Vendor Mode for Reproducible Builds
In this tutorial, you'll learn about How to Use Go Vendor Mode for Reproducible Builds. We cover key concepts, practical examples, and best practices.
The Problem
Your Go application builds fine on your machine but fails in CI because a dependency was updated or removed from the module proxy. Without vendoring, go build downloads the latest available version of each dependency at build time. If a maintainer force-pushes a tag or removes a module, your build breaks. Vendoring locks all source code inside your repository, making builds fully deterministic.
Quick Fix
1. Vendor all dependencies
go mod vendor
Expected output:
# (no output — creates vendor/ directory)
This copies all dependency source code listed in go.mod into the vendor/ directory.
2. Build with the vendored sources
go build -mod=vendor ./...
Expected output:
# (no errors — binary built from local vendor directory)
3. Verify all vendored modules are consistent
go mod verify
Expected output:
all modules verified
If verification fails, the output shows exactly which modules are inconsistent:
github.com/example/lib v1.2.3: open /home/user/go/pkg/mod/cache/download/github.com/example/lib/@v/v1.2.3.zip: no such file or directory
4. Update dependencies and re-vendor
go get github.com/example/lib@v1.3.0
go mod tidy
go mod vendor
go mod verify
5. Commit the vendor directory
git add vendor/ go.mod go.sum
git commit -m "vendor: update example/lib to v1.3.0"
In CI, always use -mod=vendor:
# .github/workflows/build.yml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- run: go build -mod=vendor -o app .
6. Exclude vendor from Docker builds
Add vendor/ to .dockerignore if you build inside Docker and use a multi-stage build:
vendor/
But keep it in the Git repository for reproducible builds.
7. Use vendor mode in GoLand or VS Code
For GoLand, set the Go build mode to "Vendor" in:
Settings → Go → Go Modules (vgo) → Vendoring mode → Vendor
For VS Code, add to .vscode/settings.json:
{
"go.buildFlags": ["-mod=vendor"],
"go.testFlags": ["-mod=vendor"]
}
8. How vendor mode affects test execution
When using -mod=vendor, tests also resolve dependencies from the vendor directory:
go test -mod=vendor ./...
Expected output:
ok github.com/example/app 0.342s
9. Check for missing vendor directory
ls vendor/
If the vendor directory does not exist, the build fails with:
go: no modules in vendor directory
Create it:
go mod vendor
Verify the directory now has the expected structure:
ls vendor/*/
Prevention
- Always use
-mod=vendorin CI pipelines — never rely on network access for builds - Run
go mod tidy && go mod vendor && go mod verifyas a pre-commit hook - Commit the entire
vendor/directory despite the increase in repository size - Review
vendor/modules.txtafter vendoring to confirm which modules and versions are included - Use
go mod downloadwithout vendor mode only in development, never in CI
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro