GitHub Actions: "Artifact storage quota has been hit"
GitHub refused to store a new artifact because the account that owns the repository has used up its artifact storage. Nothing is wrong with the build; the upload step fails, and the job fails with it.
What it looks like
The annotation on the job, from a public run on October 29, 2026:
Failed to CreateArtifact: Artifact storage quota has been hit. Unable to upload any new artifacts. Usage is recalculated every 6-12 hours. More info on storage limits: https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#calculating-minute-and-storage-spending
- The failing step is
actions/upload-artifact, or another action that stores an artifact, such asactions/upload-pages-artifactbefore a Pages deploy. - The steps after it are skipped unless their
if:allows a failure, so a job whose tests all passed ends as Failure. In one scheduled run on October 23, the unit tests and the audit passed and only the report upload failed. - Every repository of the same account or organization fails the same way, because the storage is shared. One organization's unused uploads in a few repositories failed CI in its other repositories (yumaitau/comp #1).
- Public repositories are not exempt: the six reports from October 2026 that we checked were all in public repositories.
What counts
From GitHub's billing documentation, November 3, 2026:
- Artifact storage per account: GitHub Free 500 MB, GitHub Free for organizations 500 MB, Pro 1 GB, Team 2 GB, Enterprise Cloud 50 GB. Artifacts share it with GitHub Packages.
- The cache is separate (10 GB per repository) and logs do not count.
- Usage accrues hourly over the billing month, in GB-hours. Deleting artifacts lowers the current storage, but not what the month has already accrued.
- Artifacts are kept 90 days by default. At that default, a workflow that uploads about 30 MB on every push to
mainreached 343 artifacts and about 10 GB (tally-books #43).
To see what one repository holds, with the largest artifacts first:
gh api --paginate "repos/OWNER/REPO/actions/artifacts?per_page=100" --jq '.artifacts[] | select(.expired | not) | .size_in_bytes' | awk '{s+=$1; n++} END {printf "%d artifacts, %.0f MB\n", n, s/1048576}'
gh api --paginate "repos/OWNER/REPO/actions/artifacts?per_page=100" --jq '.artifacts[] | select(.expired | not) | "\(.size_in_bytes)\t\(.created_at[:10])\t\(.name)"' | sort -rn | head
Getting uploads working again
- Delete artifacts nothing needs any more: the trash icon under Artifacts on a run's summary page, or by API. Deleted artifacts cannot be restored, so keep the ones a later job or a release still needs. For example, everything created before October 27:
gh api --paginate "repos/OWNER/REPO/actions/artifacts?per_page=100" --jq '.artifacts[] | select(.expired | not) | select(.created_at < "2026-10-27") | .id' | while read id; do gh api -X DELETE "repos/OWNER/REPO/actions/artifacts/$id"; done
- Then wait. GitHub updates storage usage within 6 to 12 hours, and uploads keep failing until it does (VAYA-App #204).
- If uploads still fail after that, the month's accrued usage may be what is over. One account still had uploads refused on October 21 with no artifacts left in any repository; its owner concluded that it would unblock in the next billing cycle or with an Actions budget above $0 (M2Watcher #15). GitHub's documentation says that without a payment method, usage is blocked once the quota is used up. Storage beyond the allowance costs US$0.25 per GB-month.
Keeping it from filling again
- Keep artifacts only as long as you need them:
- uses: actions/upload-artifact@v7 with: name: app path: dist/ retention-days: 3retention-dayscannot go above the repository's setting (90 days by default), under Settings, Actions, General, "Check, workflow run, status, artifact and log retention". Lowering that setting applies only to new artifacts, and since October 1, 2026 it also deletes checks, workflow runs and commit statuses after that time, so for artifacts alone useretention-days. - Upload only what something downloads. Several projects removed uploads that no person or job ever fetched, or kept them only on pushes to
main(yumaitau/comp #1, M2Watcher #15). - Put builds people download in a GitHub Release, which is not artifact storage, and keep the artifact for a day or two (kalio-forever #24: about 126 GB of release builds kept 90 days, now 3).
- Pass files between jobs with
actions/cachewhen they do not need to be downloaded, since the cache has its own allowance (VAYA-App #208). - Do not let an optional upload fail a passing build:
continue-on-error: trueon report and coverage uploads (beancounter #1232), and upload traces onlyif: failure().
Telling it apart
- A job that never started at all, with no steps: the account's billing blocked the job itself ("recent account payments have failed").
- An old run's logs answer "HTTP 410: Server Error": they expired (expired logs).
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, so a run that failed only at its upload step stands out, and your current branch's runs are in the status bar. Reading is free; re-running failed jobs, 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.; IntelliJ IDEA is a trademark of JetBrains s.r.o. This page is not affiliated with, sponsored or endorsed by GitHub, Inc. or JetBrains.
More: "recent account payments have failed" · Expired logs · Re-running jobs with debug logging · GitHub Actions plugins for IntelliJ IDEA compared · 日本語