Skip to content

How to Use Go Vendor Mode for Reproducible Builds

DodaTech 2 min read

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=vendor in CI pipelines — never rely on network access for builds
  • Run go mod tidy && go mod vendor && go mod verify as a pre-commit hook
  • Commit the entire vendor/ directory despite the increase in repository size
  • Review vendor/modules.txt after vendoring to confirm which modules and versions are included
  • Use go mod download without vendor mode only in development, never in CI

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro