Skip to content
Latchkey

Go "fork/exec ...: permission denied" in the Module Cache - Fix in CI

Go tried to run a binary or generator out of the module cache and the OS refused with permission denied. The cached file is not executable, or the cache was restored with ownership/permissions the build user cannot use.

What this error means

A build, go generate, or tool invocation fails with fork/exec /home/runner/go/pkg/mod/.../tool: permission denied. It commonly follows a cache restore that stripped the execute bit or changed ownership.

go output
go: running generator: fork/exec
/home/runner/go/pkg/mod/github.com/org/tool@v1.0.0/tool:
permission denied

Common causes

A restored cache lost the execute bit or changed owner

A module cache packed and restored across runs can come back without execute permissions or owned by a different user, so the build user cannot exec the cached binary.

The module cache was modified

The cache is meant to be read-only; a process that altered permissions under pkg/mod leaves it in a state Go cannot run from.

How to fix it

Clear and re-download the module cache

Wipe the cache and fetch clean copies with correct permissions.

Terminal
go clean -modcache
go mod download

Fix ownership of a restored cache

When a restored cache comes back owned by another user, reassign it to the build user.

Terminal
chown -R "$(id -u):$(id -g)" "$HOME/go/pkg/mod"

Cache the modcache so permissions survive intact

.github/workflows/ci.yml
- uses: actions/cache@v4
  with:
    path: ~/go/pkg/mod
    key: go-mod-${{ hashFiles('go.sum') }}

How to prevent it

  • Treat ~/go/pkg/mod as read-only; never change its permissions.
  • Normalize cache ownership/mode after restoring it across user contexts.
  • Use go clean -modcache to recover from a corrupted cache.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →