Safeguard
Supply Chain•

Is the Go replace directive safe to use and commit?

A replace directive swaps a Go dependency for a fork or local path and skips authentication of that module. Learn when it is safe and how to review it.

Safeguard Security Team
3 min read

A replace directive is safe when you treat it as a reviewed exception. It redirects a Go module to a fork or local folder, and the Go documentation warns that Go tools do not authenticate external modules you replace. It applies only in your main module, so it never travels to your users.

What replace does

The replace line in go.mod maps a module path, optionally with a version, to another module path or a local directory. The Go reference gives these rules:

  • It only applies in the main module's go.mod and is ignored in other modules.
  • With a version on the left, only that version is replaced. Without one, all versions are.
  • A local path on the right must begin with ./ or ../.
  • A replace alone does not add a module to the graph. A matching require is also needed.

A fork replacement looks like this:

replace example.com/theirmodule v1.2.3 => example.com/myfork/theirmodule v1.2.3-fixed

The security trade

The managing dependencies guide says plainly: "When you use the replace directive, Go tools don't authenticate external modules." Normal modules are checked against the checksum database. A replaced one is whatever your fork or folder contains at build time.

For a local path that means the code is not even versioned. Two developers can build different things from the same commit.

ReplacementMain riskMitigation
Local pathUnversioned code in the buildNever merge to the release branch
Fork at a tagFork drifts from upstream fixesTrack upstream, set a review date
Fork on a personal accountAccount or repo changesHost forks in your own organization

Steps to use replace responsibly

  1. Add a comment above the line stating why, who owns it and when to remove it.
  2. Prefer forks in an organization you control over personal repositories.
  3. Pin the fork to a tag or pseudo-version, not a moving branch.
  4. Open the upstream pull request, then delete the replace when the fix ships.
  5. Add a CI check that fails if a local path replace is present on a release branch.

A simple grep in CI works: search go.mod for lines containing => ./ or => ../.

Why it does not protect your users

Because replace is ignored outside the main module, a library author cannot ship a fork fix to consumers through it. Consumers need to add their own replace or you need to publish a new version. Remember this when you read a library's go.mod: a replace there tells you nothing about what your build uses.

Where Safeguard fits

Safeguard's dependency scanning reads the module graph and flags known vulnerabilities, and policy gates can block merges when findings cross a threshold. A free scan shows what your current go.mod resolves to.

Quick check

Does replace in a dependency's go.mod affect my build?

No. Replace directives only apply in the main module's go.mod and are ignored in other modules.

Is a replaced module checked against the checksum database?

The Go guide says Go tools do not authenticate external modules when you use replace, so review the source yourself.

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.