GitHub Actions: "Artifact download failed after 5 retries"
actions/download-artifact found the artifact and could not get it onto the runner. It tries five times, five seconds apart, and writes the reason for each failure only to the debug log (download-artifact.ts in the toolkit). So the line you see is the same whatever went wrong. Two things sort it out: whether the same artifact fails again on a re-run, and the reason in the debug log.
What it looks like
Error: Unable to download artifact(s): Unable to download and extract artifact: Artifact download failed after 5 retries.
Which case is it
Re-run the failed job and tick Enable debug logging in the dialog, or set the repository variable ACTIONS_STEP_DEBUG to true. Each attempt then ends with its reason:
##[debug]Failed to download artifact after 1 retries due to Not a valid zip file. Retrying in 5 seconds...
- "Not a valid zip file": section 1.
- "unexpected end of file" on the same artifact in every run: section 2.
- The re-run passes: section 3.
1. The artifact is not a zip
docker/build-push-action and docker/bake-action upload a build record for each build, an artifact named like owner~repo~GQJ6I2.dockerbuild, and Docker's toolkit uploads it as a plain file, not a zip (skipArchive: true in artifact.ts). download-artifact before v8 tries to unzip every artifact it downloads. A step with no name and no pattern downloads every artifact of the run, so a release job that only wanted the binaries picks up the record too.
It can pass for a while first. The step lists only the artifacts that exist when it starts, and AuroraTape's release job had run before the Docker job finished for two releases. For 1.0.2-rc.1 the Docker job finished first, and no release was created (aurora-ltfs #271). The same in pwget_rs, porcupin and novastor (#4, #44, #222). Any one of these fixes it:
- Download only what you need. Docker's README gives a pattern that leaves the records out; a pattern for your own names, such as
pwget-*, does the same.- uses: actions/download-artifact@v8 with: pattern: "!*.dockerbuild" path: release merge-multiple: true - Do not upload the record.
DOCKER_BUILD_RECORD_UPLOADset tofalseturns off only the upload; the job summary is still written (main.ts).- uses: docker/build-push-action@v7 env: DOCKER_BUILD_RECORD_UPLOAD: false with: push: true tags: ${{ steps.meta.outputs.tags }}
download-artifact@v8 on its own stops the failure but not the problem. v8 checks the Content-Type first and saves a file that is not a zip as it is (v8.0.0 release notes), so the record lands in your folder, and with merge-multiple: true a step that attaches release/* attaches it too. Keep the pattern.
The same happens to any file uploaded with archive: false (upload-artifact v7, a single file, uploaded unzipped) when a v4 to v7 download-artifact reads it. Use v8 on the downloading side.
2. A zip inside a zip
Playwright's blob reporter writes each shard's report as a zip file, and upload-artifact zips the folder again. download-artifact unzips while it streams, with unzip-stream, and two projects traced their failures to it: the inner zip's bytes can make it stop early, and the download fails with "unexpected end of file" on every attempt and every re-run. unzip -t, Python's zipfile and gh run download read the same artifact without trouble (kody #4748, EinVault #389). It depends on the bytes, so one shard fails and the next does not. kody's started with one commit and failed on every run on main after it.
EinVault uploads the shard's zip as it is and downloads it without unzipping. When sharded, Playwright names the file report-<hash>-<shard>.zip, and with archive: false the artifact takes the file's name.
# each shard
- uses: actions/upload-artifact@v7
with:
path: blob-report/*.zip
archive: false
# the merge job
- uses: actions/download-artifact@v8
with:
pattern: report-*.zip
skip-decompress: true
path: all-blob-reports
merge-multiple: true
kody instead downloads the blob reports with gh run download, which reads the zip's directory at the end of the file. That step needs a GH_TOKEN.
- run: gh run download "$GITHUB_RUN_ID" --pattern 'playwright-blob-report-*' --dir blobs
env:
GH_TOKEN: ${{ github.token }}
3. The storage, once
If the re-run passes, nothing in the workflow is wrong. tmt hit it twice in ten minutes, once in a release and once in a merge group (tmt #5743). v8.0.2 retries better when the service answers 429 and honors Retry-After (release notes), so use v8.0.2 or later. Where re-running the whole job costs a lot, as in a release, try a second time in the same job:
- id: dl
uses: actions/download-artifact@v8
continue-on-error: true
with:
name: build
path: dist
- if: steps.dl.outcome == 'failure'
run: sleep 60
- if: steps.dl.outcome == 'failure'
uses: actions/download-artifact@v8
with:
name: build
path: dist
A second try does not help sections 1 and 2: the same bytes fail the same way.
Telling it apart
- "Artifact not found for name": the step found no artifact by that name. Nothing was downloaded.
- "Digest validation failed for artifact(s)": v8 got the bytes, and their SHA-256 did not match the digest recorded at upload. v8 fails on this by default (the
digest-mismatchinput); before v8 a mismatch was only a warning. - The download passed and the files are not where the next step looks: with more than one artifact, each lands in a folder named after it, unless
merge-multipleistrue.
See failed jobs from IntelliJ IDEA
Pipeline Inbox for GitHub Actions Workflows, a plugin by Lesstep for JetBrains IDEs 2024.1 or later, lists the runs of all your repositories in an IDE tool window, with their jobs and steps, and your current branch's runs are in the status bar. Reading is free; re-running failed jobs (with debug logging if you like), cancelling, running workflows and reviewing deployments are Pro (US$1.50 a month, with a 30-day trial).
GitHub and GitHub Actions are trademarks of GitHub, Inc.; Docker is a trademark of Docker, Inc.; IntelliJ IDEA is a trademark of JetBrains s.r.o. This page is not affiliated with, sponsored or endorsed by GitHub, Inc., Docker, Inc. or JetBrains.
More: "Artifact not found for name" · "Artifact storage quota has been hit" · Docker Hub's pull rate limit · GitHub Actions plugins for IntelliJ IDEA compared · 日本語