golang/go · error

%s (in %s): The go.mod file for the module providing named

Error message

%s (in %s):
	The go.mod file for the module providing named packages contains one or
	more %s directives. It must not contain directives that would cause
	it to be interpreted differently than if it were the main module.

What it means

The package@version install workflow runs in NoRoot mode (no main module). For safety it refuses modules whose go.mod contains `replace` directives, because replaces would change dependency resolution and make the result differ from how the module behaves as a main module. Only `replace`-free go.mod files are accepted.

Source

Thrown at src/cmd/go/internal/load/pkg.go:3459

		return nil, fmt.Errorf("%s: %w", args[0], err)
	}
	if deprecation != "" {
		fmt.Fprintf(os.Stderr, "go: module %s is deprecated: %s\n", rootMod.Path, modload.ShortMessage(deprecation, ""))
	}
	data, err := ld.Fetcher().GoMod(ctx, rootMod.Path, rootMod.Version)
	if err != nil {
		return nil, fmt.Errorf("%s: %w", args[0], err)
	}
	f, err := modfile.Parse("go.mod", data, nil)
	if err != nil {
		return nil, fmt.Errorf("%s (in %s): %w", args[0], rootMod, err)
	}
	directiveFmt := "%s (in %s):\n" +
		"\tThe go.mod file for the module providing named packages contains one or\n" +
		"\tmore %s directives. It must not contain directives that would cause\n" +
		"\tit to be interpreted differently than if it were the main module."
	if len(f.Replace) > 0 {
		return nil, fmt.Errorf(directiveFmt, args[0], rootMod, "replace")
	}
	if len(f.Exclude) > 0 {
		return nil, fmt.Errorf(directiveFmt, args[0], rootMod, "exclude")
	}

	// Since we are in NoRoot mode, the build list initially contains only
	// the dummy command-line-arguments module. Add a requirement on the
	// module that provides the packages named on the command line.
	if _, err := modload.EditBuildList(ld, ctx, nil, []module.Version{rootMod}); err != nil {
		return nil, fmt.Errorf("%s: %w", args[0], err)
	}

	// Load packages for all arguments.
	pkgs := PackagesAndErrors(ld, ctx, opts, patterns)

	// Check that named packages are all provided by the same module.
	for _, pkg := range pkgs {
		var pkgErr error

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Choose a version of the module that does not contain replace directives (check `go list -m -json -versions` or the VCS tags).
  2. Clone the module locally and `go install` from within the checkout where it is the main module.
  3. Report to the maintainer that a released tag carries replace directives.
Defensive patterns

Strategy: validation

Validate before calling

// Inspect go.mod for replace directives before installing.
func hasReplaceDirective(mod, ver string) (bool, error) {
    out, err := exec.Command("go", "mod", "download", "-json", mod+"@"+ver).Output()
    if err != nil { return false, err }
    var info struct{ GoMod string }
    if err := json.Unmarshal(out, &info); err != nil { return false, err }
    data, err := os.ReadFile(info.GoMod)
    if err != nil { return false, err }
    return bytes.Contains(data, []byte("replace ")), nil
}

Prevention

When it happens

Trigger: `go install example.com/pkg@v1.0.0` where example.com/pkg's published go.mod contains one or more `replace` directives.

Common situations: Module author accidentally left local `replace` directives in a tagged release; the module uses replaces internally for development.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/a64eb27dc9c58f2f. Report an issue: GitHub.