Introduction
Artifacts in GitHub Actions are not permanent shared storage. They belong to workflow runs, expire after their retention period, and may require explicit run context or permissions to download. Many 403 and not-found failures happen because a workflow assumes an artifact is globally available when it actually belongs to a different run or has already expired.
Symptoms
download-artifactfails with403,Not Found, orArtifact has expired- Upload succeeds in one workflow, but a later workflow cannot retrieve the artifact
- The artifact exists in the UI, but automation still cannot download it
- A workflow migration from v3 to v4 changed artifact download behavior
Common Causes
- The artifact retention period expired before the consumer workflow ran
- The download step assumes same-run behavior while fetching from a different run
- The token or workflow permissions are insufficient for cross-run or cross-workflow access
- The artifact name changed and the downloader is requesting the wrong identifier
Step-by-Step Fix
- 1.Confirm which run actually created the artifact
- 2.Do not assume the artifact belongs to the currently executing workflow run. Cross-workflow pipelines need the correct producing run ID.
- uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/- 1.Check artifact retention and age
- 2.If the artifact was created days or weeks earlier, verify that its retention period still covers the download window.
- uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
retention-days: 30- 1.Use the correct download scope and permissions
- 2.For same-run downloads, the name is usually enough. For cross-run downloads, the workflow needs the right run context and access token behavior.
- uses: actions/download-artifact@v4
with:
name: build-output- 1.Keep artifact naming stable across producer and consumer jobs
- 2.Renamed artifacts or matrix-generated names often create false 403 or not-found debugging paths when the real issue is simply a mismatched name.
Prevention
- Treat artifacts as short-lived workflow outputs, not long-term storage
- Set retention explicitly for pipelines that rely on delayed downloads
- Pass artifact names and producing run IDs intentionally between workflows
- Keep upload and download actions on current major versions to avoid behavioral drift