When actions/setup-go@v6 is called twice in the same job, the second invocation's cache restore fails because all the Go module files already exist on disk from the first restore.
Go module cache files under ~/go/pkg/mod are read-only by design (go get removes write permissions), so when the second tar extraction attempts to overwrite them, it fails with thousands of Cannot open: File exists errors and ultimately:
##[warning]Failed to restore: "/usr/bin/tar" failed with error: The process '/usr/bin/tar' failed with exit code 2
Action version
actions/setup-go@v6
Platform
Runner type
Tools version
Go 1.24.5 (read from go.mod)
Repro steps
Any job that calls setup-go twice with caching enabled will trigger this.
Minimal example:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
# cache: true (default)
# Any second call to setup-go with cache enabled triggers the issue
- uses: actions/setup-go@v6
with:
go-version-file: go.mod
This is especially easy to hit when using composite actions or reusable workflows that internally call setup-go, since the caller may not be aware of the duplicate invocation.
First setup-go call:
- Installs Go, restores ~508MB module cache successfully
- Extracts to
~/go/pkg/mod and ~/.cache/go-build
Second setup-go call:
- Finds Go already in tool cache, resolves the same cache key
- Downloads and attempts to extract the same ~508MB archive
tar fails on every file: Cannot open: File exists
- Emits
##[warning]Failed to restore
Expected behavior
When setup-go is called multiple times in the same job with the same cache key, the second invocation should gracefully handle the case where cached files already exist on disk. Possible approaches:
- Skip restore if already done — detect that the cache was already restored in this job (e.g., via an environment variable or state) and skip the second restore entirely
- Use
tar --skip-old-files — avoid errors when files already exist during extraction
- Handle tar exit code 2 as non-fatal — when the only errors are "File exists", treat the restore as successful
Actual behavior
The second cache restore downloads the full archive, attempts extraction, fails with thousands of ##[error] lines for every file, and emits a ##[warning]Failed to restore message. While the job typically succeeds (since the files are already present), this produces noisy logs and unnecessary network traffic.
Related issues
When
actions/setup-go@v6is called twice in the same job, the second invocation's cache restore fails because all the Go module files already exist on disk from the first restore.Go module cache files under
~/go/pkg/modare read-only by design (go getremoves write permissions), so when the secondtarextraction attempts to overwrite them, it fails with thousands ofCannot open: File existserrors and ultimately:Action version
actions/setup-go@v6Platform
Runner type
Tools version
Go 1.24.5 (read from
go.mod)Repro steps
Any job that calls
setup-gotwice with caching enabled will trigger this.Minimal example:
This is especially easy to hit when using composite actions or reusable workflows that internally call
setup-go, since the caller may not be aware of the duplicate invocation.First
setup-gocall:~/go/pkg/modand~/.cache/go-buildSecond
setup-gocall:tarfails on every file:Cannot open: File exists##[warning]Failed to restoreExpected behavior
When
setup-gois called multiple times in the same job with the same cache key, the second invocation should gracefully handle the case where cached files already exist on disk. Possible approaches:tar --skip-old-files— avoid errors when files already exist during extractionActual behavior
The second cache restore downloads the full archive, attempts extraction, fails with thousands of
##[error]lines for every file, and emits a##[warning]Failed to restoremessage. While the job typically succeeds (since the files are already present), this produces noisy logs and unnecessary network traffic.Related issues