golang/go · error

internal error: invalid binary cache entry: not a directory

Error message

internal error: invalid binary cache entry: not a directory

What it means

When caching executable outputs, the cache uses a directory structure: the output path is a directory containing the named executable file. If os.Stat shows the path exists but is NOT a directory, the cache is in an inconsistent state — a regular file exists where the code expects a directory to hold the executable. This is flagged as an internal error because it represents a format-level violation.

Source

Thrown at src/cmd/go/internal/cache/cache.go:618

	info, err := os.Stat(name)
	if executableName != "" {
		// This is an executable file. The file at name won't hold the output itself, but will
		// be a directory that holds the output, named according to executableName. Check to see
		// if the directory already exists, and if it does not, create it. Then reset name
		// to the name we want the output written to.
		if err != nil {
			if !os.IsNotExist(err) {
				return err
			}
			if err := os.Mkdir(name, 0o777); err != nil {
				return err
			}
			if info, err = os.Stat(name); err != nil {
				return err
			}
		}
		if !info.IsDir() {
			return errors.New("internal error: invalid binary cache entry: not a directory")
		}

		// directory exists. now set name to the inner file
		name = filepath.Join(name, executableName)
		info, err = os.Stat(name)
	}
	if err == nil && info.Size() == size {
		// Check hash.
		if f, err := os.Open(name); err == nil {
			h := sha256.New()
			io.Copy(h, f)
			f.Close()
			var out2 OutputID
			h.Sum(out2[:0])
			if out == out2 {
				return nil
			}
		}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Run go clean -cache to remove all entries and rebuild with the current format
  2. Ensure you are using a consistent Go toolchain version across builds
  3. Remove the specific corrupt cache directory entry if the path is known
  4. If migrating Go versions, always clean the cache after upgrading

Example fix

// before: stale cache from previous Go version expects directory but finds file
// $ go build ./... # fails with 'internal error: invalid binary cache entry: not a directory'

// after: clean cache after Go version upgrade
// $ go clean -cache && go build ./...
Defensive patterns

Strategy: validation

Validate before calling

// Before builds, verify the cache isn't in a mixed-format state.
// Simplest check: if Go version changed, always clean.
func ensureCacheFormatConsistent(goVersion string) {
    marker := filepath.Join(os.Getenv("GOCACHE"), ".go-version")
    cached, err := os.ReadFile(marker)
    if err == nil && string(cached) == goVersion {
        return // same version, cache is likely fine
    }
    fmt.Println("Go version changed or unknown — cleaning cache")
    exec.Command("go", "clean", "-cache").Run()
    os.WriteFile(marker, []byte(goVersion), 0644)
}

Type guard

func isInvalidBinaryEntry(err error) bool {
    return err != nil && strings.Contains(err.Error(), "invalid binary cache entry")
}

Try / catch

// This is a write-path error (put), not a read-path error.
// It occurs when the cache tries to store an executable.
// The error is returned directly, not wrapped in entryNotFoundError.
//
// if err := cache.Put(...); err != nil {
//     if isInvalidBinaryEntry(err) {
//         // Clean cache and retry
//         exec.Command("go", "clean", "-cache").Run()
//         cache.Put(...) // retry
//     }
// }

Prevention

When it happens

Trigger: The executable caching path in the put() function (cache.go:617) finds that 'name' exists (os.Stat succeeds), but info.IsDir() returns false. The code path is entered when executableName != '' and an existing entry was found at the expected path.

Common situations: Cache format migration issue between Go versions that changed how executables are stored (old version wrote a plain file, new version expects a directory); manual tampering with cache files; partial restore from backup mixing formats; a previous crash left the cache in an inconsistent state.

Related errors


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