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

  1. Run `go clean -modcache` to wipe and re-download the cache cleanly.
  2. Delete just the offending entry (`rm -rf GOMODCACHE/<enc>@<encVer>`) and run `go mod download` again.
  3. 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

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.