golang/go · error
failed to create cache directory: %w
Error message
failed to create cache directory: %w
What it means
Thrown by `modfetch.SideLock` when `os.MkdirAll` fails to create the `cache/lock` parent directory inside GOMODCACHE. SideLock acquires a mutex on a file in the module cache to serialize edits to files outside the cache (go.sum, go.mod). If the cache directory structure cannot be created — due to permissions, disk full, or path issues — this wraps the underlying OS error with %w.
Source
Thrown at src/cmd/go/internal/modfetch/cache.go:178
}
if err := os.MkdirAll(filepath.Dir(path), 0o777); err != nil {
return nil, err
}
return lockedfile.MutexAt(path).Lock()
}
// SideLock locks a file within the module cache that previously guarded
// edits to files outside the cache, such as go.sum and go.mod files in the
// user's working directory.
// If err is nil, the caller MUST eventually call the unlock function.
func SideLock(ctx context.Context) (unlock func(), err error) {
if err := checkCacheDir(ctx); err != nil {
return nil, err
}
path := filepath.Join(cfg.GOMODCACHE, "cache", "lock")
if err := os.MkdirAll(filepath.Dir(path), 0o777); err != nil {
return nil, fmt.Errorf("failed to create cache directory: %w", err)
}
return lockedfile.MutexAt(path).Lock()
}
// A cachingRepo is a cache around an underlying Repo,
// avoiding redundant calls to ModulePath, Versions, Stat, Latest, and GoMod (but not CheckReuse or Zip).
// It is also safe for simultaneous use by multiple goroutines
// (so that it can be returned from Lookup multiple times).
// It serializes calls to the underlying Repo.
type cachingRepo struct {
path string
versionsCache par.ErrCache[string, *Versions]
statCache par.ErrCache[string, *RevInfo]
latestCache par.ErrCache[struct{}, *RevInfo]
gomodCache par.ErrCache[string, []byte]
once sync.OnceView on GitHub (pinned to b6b368adc5)
Solutions
- Check and fix permissions on GOMODCACHE: `chmod -R u+w $(go env GOMODCACHE)`
- Ensure GOMODCACHE points to a writable directory
- Free disk space if full
- Verify the path is valid and accessible: `ls -la $(go env GOMODCACHE)/cache/`
Example fix
# before: GOMODCACHE points to read-only location export GOMODCACHE=/usr/local/go/pkg/mod # after: point to writable location export GOMODCACHE=$HOME/go/pkg/mod
Defensive patterns
Strategy: validation
Validate before calling
// Verify cache directory is writable before operations
import "os"
func ensureCacheWritable() error {
cacheDir := os.Getenv("GOMODCACHE")
if cacheDir == "" {
cacheDir = filepath.Join(os.Getenv("GOPATH"), "pkg", "mod")
}
testFile := filepath.Join(cacheDir, "cache", ".writetest")
return os.WriteFile(testFile, []byte("ok"), 0644)
} Prevention
- Ensure GOMODCACHE is on a writable filesystem with adequate permissions
- Check disk space before running module-heavy operations
- In containers, mount GOMODCACHE on a writable volume
When it happens
Trigger: Calling SideLock when GOMODCACHE/cache/ cannot be created. MkdirAll fails due to: permission denied on a parent directory, read-only filesystem, disk full, invalid path characters, or GOMODCACHE pointing to a location that can't be created.
Common situations: GOMODCACHE set to a read-only directory; insufficient permissions on the cache root; disk full; GOMODCACHE on a network mount with write failures; containerized environments with volume permission issues.
Related errors
- %s %s: missing ziphash: %v
- %s %s: %v
- %s %s: zip has been modified (%v)
- %s %s: dir has been modified (%v)
- module cache not found: neither GOMODCACHE nor GOPATH is set
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/8a012b6c8f80be66.
Report an issue: GitHub.