golang/go · error

import lookup disabled by -mod=%s (%s)

Error message

import lookup disabled by -mod=%s
	(%s)

What it means

Same precondition as error 1061 (readonly/vendor mode blocks import lookup) but emitted when the mode was set IMPLICITLY with a recorded reason (cfg.BuildModExplicit false, cfg.BuildModReason set). The message appends the human-readable reason so the user knows why -mod was enabled. The wrapped ImportMissingError still carries the unresolved path.

Source

Thrown at src/cmd/go/internal/modload/import.go:625

		return module.Version{}, &ImportMissingError{
			Path:                      path,
			isStd:                     true,
			modContainingCWD:          ld.MainModules.ModContainingCWD(),
			allowMissingModuleImports: ld.allowMissingModuleImports,
		}
	}

	if (cfg.BuildMod == "readonly" || cfg.BuildMod == "vendor") && !ld.allowMissingModuleImports {
		// In readonly mode, we can't write go.mod, so we shouldn't try to look up
		// the module. If readonly mode was enabled explicitly, include that in
		// the error message.
		// In vendor mode, we cannot use the network or module cache, so we
		// shouldn't try to look up the module
		var queryErr error
		if cfg.BuildModExplicit {
			queryErr = fmt.Errorf("import lookup disabled by -mod=%s", cfg.BuildMod)
		} else if cfg.BuildModReason != "" {
			queryErr = fmt.Errorf("import lookup disabled by -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason)
		}
		return module.Version{}, &ImportMissingError{
			Path:                      path,
			QueryErr:                  queryErr,
			modContainingCWD:          ld.MainModules.ModContainingCWD(),
			allowMissingModuleImports: ld.allowMissingModuleImports,
		}
	}

	// Look up module containing the package, for addition to the build list.
	// Goal is to determine the module, download it to dir,
	// and return m, dir, ImportMissingError.
	fmt.Fprintf(os.Stderr, "go: finding module for package %s\n", path)

	mg, err := rs.Graph(ld, ctx)
	if err != nil {
		return module.Version{}, err
	}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Run 'go get <importpath>' to add the dependency, then rebuild.
  2. Inspect and unset the implicit source: 'go env GOFLAGS' and remove -mod=readonly, or delete the GOFLAGS entry.
  3. If vendor mode was auto-selected, run 'go mod vendor' after adding the dep, or remove the vendor/ dir to fall back to mod mode.
  4. Override per-command: 'go build -mod=mod ./...' to allow the update this once.

Example fix

// before
$ go env GOFLAGS
-mod=readonly
$ go build ./...
// import lookup disabled by -mod=readonly
//	(go: -mod=readonly set in GOFLAGS)

// after
$ go env -u GOFLAGS          // or: export GOFLAGS=
$ go get <newdep> && go build ./...
Defensive patterns

Strategy: validation

Validate before calling

// Detect implicit -mod source before building.
goflags := os.Getenv("GOFLAGS")
if strings.Contains(goflags, "-mod=readonly") || strings.Contains(goflags, "-mod=vendor") {
    if err := exec.Command("go", "get", "./...").Run(); err != nil { return err }
}
// or surface the cause to the user:
if reason, _ := exec.Command("go", "env", "GOFLAGS").Output(); len(reason) > 0 {
    fmt.Printf("note: GOFLAGS=%s may block import lookup\n", strings.TrimSpace(string(reason)))
}

Try / catch

out, err := exec.Command("go", "build", "./...").CombinedOutput()
if err != nil && bytes.Contains(out, []byte("import lookup disabled by -mod=")) {
    // parse the reason line and unset its source (e.g. GOFLAGS)
    fmt.Fprintln(os.Stderr, "clearing implicit -mod; re-run after 'go get'")
    os.Unsetenv("GOFLAGS")
    out, err = exec.Command("go", "build", "./...").CombinedOutput()
}
return err

Prevention

When it happens

Trigger: An import is missing while BuildMod is readonly/vendor due to GOFLAGS=-mod=readonly, GOFLAGS=-mod=vendor, or because a vendored directory was detected, AND cfg.BuildModReason is non-empty (e.g. 'go: -mod=readonly set in GOFLAGS'). ld.allowMissingModuleImports is false.

Common situations: A shell rc file or CI image exports GOFLAGS=-mod=readonly globally; a project auto-entered vendor mode because ./vendor exists; the user is confused why -mod is active since they did not type it.

Related errors


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