golang/go · error · DownloadDirPartialError
not a directory
Error message
not a directory
What it means
DownloadDir expects the cached module path GOMODCACHE/<enc>@<encVer> to be a directory. os.Stat returns an entry at that path whose IsDir() is false (a regular file), so the cache is treated as partially populated and a DownloadDirPartialError (equivalent to fs.ErrNotExist) is returned.
Source
Thrown at src/cmd/go/internal/modfetch/cache.go:103
if !gover.ModIsValid(m.Path, m.Version) {
return "", fmt.Errorf("non-semver module version %q", m.Version)
}
if module.CanonicalVersion(m.Version) != m.Version {
return "", fmt.Errorf("non-canonical module version %q", m.Version)
}
encVer, err := module.EscapeVersion(m.Version)
if err != nil {
return "", err
}
// Check whether the directory itself exists.
dir := filepath.Join(cfg.GOMODCACHE, enc+"@"+encVer)
if fi, err := os.Stat(dir); os.IsNotExist(err) {
return dir, err
} else if err != nil {
return dir, &DownloadDirPartialError{dir, err}
} else if !fi.IsDir() {
return dir, &DownloadDirPartialError{dir, errors.New("not a directory")}
}
// Check if a .partial file exists. This is created at the beginning of
// a download and removed after the zip is extracted.
partialPath, err := CachePath(ctx, m, "partial")
if err != nil {
return dir, err
}
if _, err := os.Stat(partialPath); err == nil {
return dir, &DownloadDirPartialError{dir, errors.New("not completely extracted")}
} else if !os.IsNotExist(err) {
return dir, err
}
// Special case: ziphash is not required for the golang.org/fips140 module,
// because it is unpacked from a file in GOROOT, not downloaded.
// We've already checked that it's not a partial unpacking, so we're happy.
if m.Path == "golang.org/fips140" {View on GitHub (pinned to b6b368adc5)
Solutions
- Run `go clean -modcache` to wipe and re-download the cache cleanly.
- Delete just the offending entry (`rm -rf GOMODCACHE/<enc>@<encVer>`) and run `go mod download` again.
- Confirm GOMODCACHE points to a writable directory you control and treat it as read-only afterwards.
Defensive patterns
Strategy: fallback
Validate before calling
// Before relying on a cached module dir, verify it is a directory:
// fi, err := os.Stat(dir)
// if err == nil && !fi.IsDir() { /* clean and re-download */ } Try / catch
// On *modfetch.DownloadDirPartialError (which wraps fs.ErrNotExist), // run `go clean -modcache` (or remove the entry) and retry the build.
Prevention
- Treat GOMODCACHE as read-only; do not manually create or replace entries.
- Run `go clean -modcache` when the cache is suspected corrupt.
When it happens
Trigger: The path GOMODCACHE/<enc>@<encVer> exists but is a file rather than a directory, so DownloadDir refuses to return it.
Common situations: Corrupted module cache from a crashed or interrupted extraction; manual tampering inside GOMODCACHE; restoring GOMODCACHE from a bad backup that flattened directories; partial copy of the cache between machines.
Related errors
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/83d4503ba0a981bd.
Report an issue: GitHub.