Safeguard
Developer Tools•

Should CI build Go in readonly mode? What the setting protects

Since Go 1.16, readonly is the default: the build fails if go.mod needs changes. Why that matters for CI, which settings to avoid, and what to add.

Safeguard Security Team
3 min read

Yes, and you already get it by default. Since Go 1.16 the go command acts as if mod equals readonly: if go.mod needs changes, the build reports an error instead of editing the file. In CI, keep that default so a build cannot silently change which dependencies it uses.

What the flag does

The Go reference describes the readonly setting as ignoring the vendor directory and reporting an error when go.mod needs updating. The mod setting does the opposite: it updates go.mod automatically, for example when an imported package is not provided by any known module.

Before Go 1.16, mod was the default, so builds could change dependencies on their own.

Why it matters for supply chain

A build that edits its own requirements is a build whose result you did not review. With readonly, a missing requirement shows up as a failure that a person has to resolve and commit.

SettingBehaviorCI risk
readonlyErrors if go.mod needs changesLow, changes must be committed
modUpdates go.mod during the buildHigher, dependency changes happen unreviewed
vendorUses the vendor directoryLow, if vendor is committed and checked

If your go line in go.mod is 1.14 or higher and a vendor directory is present, the go command acts as if vendor were set. Otherwise it acts as readonly.

A CI checklist

  1. Do not set the build to mod in CI unless a job exists specifically to update dependencies.
  2. Run a tidy check that does not write files. The reference describes a diff option for go mod tidy that prints needed changes and exits non-zero if the diff is not empty.
  3. Run go mod verify to check that cached modules were not modified after download. The reference says it exits non-zero if anything changed.
  4. Keep go.sum committed.
  5. Scan the result with a tool that reads go.mod and checks advisories.
go mod tidy -diff
go mod verify

What these checks do not do

Neither check says a dependency is safe. They say the build matches what was committed. A bad version that you committed deliberately will pass. That is what a vulnerability scan is for.

Where this fits in a pipeline

Place these checks early, before tests, so a dependency mismatch fails fast and the message points at go.mod rather than at a confusing test failure. Pair them with a scheduled scan, since new advisories appear after code is merged and a build that passed last month can have a known flaw today.

Quick check

Is readonly the default in current Go versions?

Yes, since Go 1.16, unless a vendor directory is present and your go line is 1.14 or higher, in which case vendor mode applies.

Does go mod verify compare against go.sum?

Not for content. It compares cached modules against hashes recorded when they were first downloaded, and it reports changed modules.

Safeguard's policies and gates can block a pull request that introduces a known vulnerable dependency. See what it finds with the free scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.