Go applies replace and exclude directives only in the main module's go.mod and ignores them in every other module. A library you import can contain a replace line, but your build will not honor it. Each service that needs a patched version must set it in its own go.mod.
What the Go reference says
The Go modules reference states that replace directives apply only in the main module's go.mod and are ignored in other modules. The same holds for exclude.
The practical effect, in the reference's framing, is that a dependency cannot silently redirect your build. Your build list comes from your own go.mod, and from a go.work file if you use workspaces.
How this causes a cross team dispute
A shared internal library team finds a vulnerable module version. They add a replace line pointing at a patched fork or version in the library's go.mod, run their tests, and announce the problem is fixed.
Service teams that import the library see no change. Their scanners still flag the old version, and now they are told the fix has shipped. Both sides are confused, and the library team may feel blamed for a problem they believe they solved.
What actually fixes it for consumers
Two routes work, and the choice is a team agreement.
- Raise the requirement in the library. Update the library's require line to a fixed version and release it. Consumers pick it up when they update the library. Minimal version selection, as the reference explains, uses the highest version any requirement names, so the fixed version wins once the library asks for it.
- Set it in each service. A service adds its own require, or its own replace or exclude, in its go.mod. This works at once without waiting for a library release.
Route one fixes everyone eventually. Route two fixes one service now. Most organizations need both: services patch immediately, and the library team ships the requirement change so the patches can be removed.
Know what replace does and does not do
From the reference:
- A replace does not add a module to the graph. A require for the replaced version is also needed, and a replace has no effect if that version is not required.
- A replacement can change the graph, because the replacement may have different dependencies of its own.
- An exclude removes a version from the graph, and requirements on it move to the next higher version.
If your fix is a fork, remember that you now maintain it. Record who owns the fork and when you will return to the upstream module.
A short agreement between teams
- Library team: never rely on replace in the library to protect consumers. Raise requirements and release.
- Service teams: apply a local fix when an advisory lands, tag it with the advisory, and remove it after the library release.
- Everyone: verify with the module graph commands after the change, not by reading go.mod alone.
Quick check
Does a replace in a dependency's go.mod affect my build?
No. The Go reference says replace directives apply only in the main module's go.mod and are ignored in other modules.
How can a library team protect its consumers?
Raise the require line to the fixed version and publish a release. Consumers then get the fixed version through normal resolution.
Sources
Last reviewed: 19 October 2026.