golang/go · error

neither GOPATH nor GOMODCACHE are set

Error message

neither GOPATH nor GOMODCACHE are set

What it means

Thrown by codehost.WorkDir when cfg.GOMODCACHE is empty, which only happens if neither GOPATH nor GOMODCACHE is set. WorkDir computes the VCS cache directory under GOMODCACHE/cache/vcs, so an empty cache root makes it impossible to place the work dir.

Source

Thrown at src/cmd/go/internal/modfetch/codehost/codehost.go:219

		return false
	}
	return true
}

// ShortenSHA1 shortens a SHA1 hash (40 hex digits) to the canonical length
// used in pseudo-versions (12 hex digits).
func ShortenSHA1(rev string) string {
	if AllHex(rev) && len(rev) == 40 {
		return rev[:12]
	}
	return rev
}

// WorkDir returns the name of the cached work directory to use for the
// given repository type and name.
func WorkDir(ctx context.Context, typ, name string) (dir, lockfile string, err error) {
	if cfg.GOMODCACHE == "" {
		return "", "", fmt.Errorf("neither GOPATH nor GOMODCACHE are set")
	}

	// We name the work directory for the SHA256 hash of the type and name.
	// We intentionally avoid the actual name both because of possible
	// conflicts with valid file system paths and because we want to ensure
	// that one checkout is never nested inside another. That nesting has
	// led to security problems in the past.
	if strings.Contains(typ, ":") {
		return "", "", fmt.Errorf("codehost.WorkDir: type cannot contain colon")
	}
	key := typ + ":" + name
	dir = filepath.Join(cfg.GOMODCACHE, "cache/vcs", fmt.Sprintf("%x", sha256.Sum256([]byte(key))))

	xLog, buildX := cfg.BuildXWriter(ctx)
	if buildX {
		fmt.Fprintf(xLog, "mkdir -p %s # %s %s\n", filepath.Dir(dir), typ, name)
	}
	if err := os.MkdirAll(filepath.Dir(dir), 0777); err != nil {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Set GOPATH: 'go env -w GOPATH=$HOME/go'.
  2. Or set GOMODCACHE directly: 'go env -w GOMODCACHE=$HOME/go/pkg/mod'.
  3. Verify with 'go env GOPATH GOMODCACHE' that both are non-empty.
  4. In containers, add 'ENV GOPATH=/go' to the Dockerfile.

Example fix

# before
docker run --rm -e GOPATH= golang go get example.com/mod
# after
docker run --rm -e GOPATH=/go golang go get example.com/mod
# or persistently
go env -w GOPATH=$HOME/go
Defensive patterns

Strategy: validation

Validate before calling

func validateGoEnv() error {
    gopath := os.Getenv("GOPATH")
    gomodcache := os.Getenv("GOMODCACHE")
    if gopath == "" && gomodcache == "" {
        return fmt.Errorf("neither GOPATH nor GOMODCACHE is set")
    }
    return nil
}

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Calling codehost.WorkDir (indirectly via go get/go mod download for a VCS-backed module) in an environment where both GOPATH and GOMODCACHE are unset — e.g. a stripped-down container, a misconfigured CI image, or GOFLAGS=-mod=mod with GOENV disabled.

Common situations: Minimal docker images that don't set GOPATH; CI environments that clear environment variables; GOPATH explicitly set to empty string.

Related errors


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