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
- Set GOPATH: 'go env -w GOPATH=$HOME/go'.
- Or set GOMODCACHE directly: 'go env -w GOMODCACHE=$HOME/go/pkg/mod'.
- Verify with 'go env GOPATH GOMODCACHE' that both are non-empty.
- 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
- Always set GOPATH in Dockerfiles: 'ENV GOPATH=/go'.
- In CI, source a go env setup script before running builds.
- Avoid unsetting environment variables in build scripts.
- Add a pre-build assertion that GOPATH/GOMODCACHE are non-empty.
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
- GOPATH entry cannot start with shell metacharacter '~': %q
- GOPATH entry is relative; must be absolute path: %q
- GOMODCACHE entry is relative; must be absolute path: %q
- module cache not found: neither GOMODCACHE nor GOPATH is set
- GOMODCACHE entry is relative; must be absolute path: %q.\n
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/88aeaa6a2dcf2b20.
Report an issue: GitHub.