golang/go · error

codehost.WorkDir: can't find or create lock file: %v

Error message

codehost.WorkDir: can't find or create lock file: %v

What it means

Thrown by codehost.WorkDir when lockedfile.MutexAt(lockfile).Lock() fails for the per-repo .lock file under GOMODCACHE/cache/vcs. The %v is the underlying error from the lock acquisition (usually permission or I/O). The lock serializes access to a cached VCS checkout.

Source

Thrown at src/cmd/go/internal/modfetch/codehost/codehost.go:248

	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 {
		return "", "", err
	}

	lockfile = dir + ".lock"
	if buildX {
		fmt.Fprintf(xLog, "# lock %s\n", lockfile)
	}

	unlock, err := lockedfile.MutexAt(lockfile).Lock()
	if err != nil {
		return "", "", fmt.Errorf("codehost.WorkDir: can't find or create lock file: %v", err)
	}
	defer unlock()

	data, err := os.ReadFile(dir + ".info")
	info, err2 := os.Stat(dir)
	if err == nil && err2 == nil && info.IsDir() {
		// Info file and directory both already exist: reuse.
		have := strings.TrimSuffix(string(data), "\n")
		if have != key {
			return "", "", fmt.Errorf("%s exists with wrong content (have %q want %q)", dir+".info", have, key)
		}
		if buildX {
			fmt.Fprintf(xLog, "# %s for %s %s\n", dir, typ, name)
		}
		return dir, lockfile, nil
	}

	// Info file or directory missing. Start from scratch.

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Check permissions on GOMODCACHE/cache/vcs: 'ls -la $(go env GOMODCACHE)/cache/vcs/'.
  2. Remove stale lock files: 'find $(go env GOMODCACHE)/cache/vcs -name *.lock -delete' (only when no go commands are running).
  3. On network filesystems, move GOMODCACHE to a local disk.
  4. Clear and rebuild the VCS cache: 'go clean -cache'.

Example fix

# before: lock file owned by root on a shared FS
$ go get example.com/mod
... can't find or create lock file: ...
# after
sudo chown -R $USER $(go env GOMODCACHE)/cache
go get example.com/mod
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

null

Try / catch

// Retry on transient lock failures with backoff
func withLockRetry(fn func() error) error {
    for i := 0; i < 3; i++ {
        err := fn()
        if err == nil { return nil }
        if isLockErr(err) && i < 2 {
            time.Sleep(time.Duration(1<<i) * time.Second)
            continue
        }
        return err
    }
    return fmt.Errorf("lock retry exhausted")
}

Prevention

When it happens

Trigger: Concurrent or sequential go commands accessing the same cached VCS repo when the lock file or its parent directory is inaccessible, read-only, or on a filesystem that doesn't support the locking mechanism.

Common situations: Cache directory chowned to another user; NFS/CIFS mounts with broken advisory locking; antivirus or security software holding the file open on Windows; disk full preventing lock file creation.

Related errors


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