GitLab CI Error Guide: 'Downloading artifacts ... 404 Not Found' Fix
Fix GitLab's 'Downloading artifacts from coordinator... 404 Not Found': set artifacts:paths and expire_in, wire up needs:artifacts, and list dependencies.
- #gitlab-cicd
- #troubleshooting
- #errors
- #artifacts
Exact Error Message
A downstream job fails (or warns) while trying to pull artifacts from an earlier job:
Downloading artifacts from coordinator... not found
id=128431 responseStatus=404 Not Found status=404 Not Found token=AbCdEf
WARNING: Downloading artifacts from coordinator... could not be retrieved
ERROR: Job failed: artifacts for job build could not be retrieved
Sometimes there is no error line at all — the consuming job runs, but the files it expected from a prior job simply are not on disk, and a later command fails with No such file or directory.
What the Error Means
A 404 here means the GitLab coordinator was asked for an artifact archive that no longer exists or was never created. The runner contacts the coordinator to download the artifacts of the jobs this one depends on; if the archive has expired, was never uploaded, or is not in this job’s dependency set, the coordinator returns 404 and the runner reports it could not retrieve the artifacts.
This is not about artifacts being too large — that is a separate failure at upload time, covered in the artifacts too large / cache upload guide. This guide is the download side: the producing job’s output is missing, expired, or not wired to the consumer. The fix is in how artifacts are declared and which jobs depend on them.
Common Causes
- Artifacts expired before the consumer ran. A short
expire_in(or a long-delayed downstream job) means the archive was deleted by the time the consumer asked for it. - The producing job never defined
artifacts:paths. Withoutartifacts:paths, nothing is uploaded, so there is nothing to download. dependencies:orneeds:artifactsexcludes it. The consumer’sdependencies:list omits the producer, or aneeds:entry hasartifacts: false, so the producer’s archive is intentionally skipped.- The producing job is on a different ref. The artifact you expect was built on another branch/pipeline; the current pipeline’s job has no such artifact.
- The producing job did not run (filtered by rules) or failed. No run means no artifact to fetch.
needs:artifacts:falseset unintentionally. Usingneeds:for ordering but disabling artifact transfer drops the files.
How to Reproduce the Error
A producer with a short expiry and a consumer that runs later:
stages: [build, deploy]
build:
stage: build
script: ["make build"]
artifacts:
paths: ["dist/"]
expire_in: 1 min # too short; deletes before deploy runs
deploy:
stage: deploy
script: ["ls dist/ && make deploy"]
needs: ["build"]
If deploy starts more than a minute after build, the archive is gone:
WARNING: Downloading artifacts from coordinator... could not be retrieved
responseStatus=404 Not Found
Or a consumer that ordered on build but disabled artifact transfer:
deploy:
needs:
- job: build
artifacts: false # files never arrive
script: ["ls dist/"] # No such file or directory
Diagnostic Commands
Read the consuming job’s log for the exact response status:
Downloading artifacts from coordinator... not found responseStatus=404
Confirm the producer actually declares and uploads artifacts:
# In .gitlab-ci.yml: does build have artifacts:paths?
glab ci lint --include | grep -A4 'build:'
Check the producer’s expiry against how long downstream takes to start:
artifacts:
paths: ["dist/"]
expire_in: 1 hour
List which jobs the consumer depends on for artifacts:
glab ci lint --include | grep -E 'needs|dependencies'
In the UI, open the producing job, then Browse its artifacts to confirm the files are present and not expired (the artifacts panel shows the expiry countdown). The Pipeline Editor’s Full configuration (merged YAML) view confirms artifacts:, needs:, and dependencies: after includes are resolved.
Step-by-Step Resolution
Declare artifacts:paths and a sufficient expire_in on the producer:
build:
stage: build
script: ["make build"]
artifacts:
paths: ["dist/"]
expire_in: 1 week # long enough for downstream jobs and reruns
Wire the consumer to pull those artifacts with needs: (the modern, explicit form). By default a needs: entry transfers artifacts — keep it that way:
deploy:
stage: deploy
script: ["ls dist/ && make deploy"]
needs:
- job: build
artifacts: true # explicit; default is true
Or use dependencies: to control exactly which artifacts are fetched when you rely on stage ordering rather than needs::
deploy:
stage: deploy
script: ["make deploy"]
dependencies: ["build"] # fetch only build's artifacts
An empty dependencies: [] fetches no artifacts — use it deliberately to opt out, and never leave the producer off the list when you actually need its files.
If the producer is conditional, make sure it runs when the consumer does. Align rules: so the producing job is present in the same pipeline (see the needs not in pipeline guide).
If you only need ordering, not files, set artifacts: false intentionally and do not reference the missing files in the consumer’s script.
Re-run the pipeline and confirm the consuming job’s log shows Downloading artifacts from coordinator... ok and the expected files exist.
Prevention and Best Practices
- Always pair
artifacts:pathswith anexpire_inlong enough to outlast downstream jobs, manual approvals, and reruns; a too-short expiry is the most common 404 cause. - Prefer
needs:for both ordering and artifact transfer, and be explicit withartifacts: true/falseso intent is clear. - When using
dependencies:, list every producer the job actually consumes; an omitted producer silently drops its files. - Keep producer and consumer
rules:aligned so the producing job is present whenever the consumer runs. - Use the job’s Browse artifacts view and the merged-YAML view to confirm files exist and dependencies resolve before debugging the runner.
- The free incident assistant can turn an artifact 404 log into a likely-cause-and-fix; more patterns live in the GitLab CI/CD guides.
Related Errors
- Artifacts too large / cache upload failed — the upload side, where the producer’s artifact exceeds size limits, versus this download 404.
- job needs job, but it was not added to the pipeline — when the producing job is filtered out entirely, so there is nothing to download.
- Invalid CI config / YAML validation errors — a malformed
artifacts:ordependencies:block fails schema validation instead.
Frequently Asked Questions
Why does the consumer get a 404 when the build job clearly succeeded?
The most common reason is that the artifact expired. The build succeeded and uploaded its archive, but expire_in deleted it before the downstream job (or a rerun) requested it. Increase expire_in so it outlasts the whole pipeline plus any manual gates.
What is the difference between needs: and dependencies: for artifacts?
needs: controls execution order and, by default, transfers the named jobs’ artifacts. dependencies: only controls which jobs’ artifacts are downloaded (within stage ordering). Use needs: for the explicit DAG; use dependencies: when you rely on stages but want to restrict which artifacts are fetched.
My deploy job runs but the files are missing — no 404. Why?
You likely set artifacts: false on the needs: entry, or used dependencies: [], so the job orders correctly but downloads nothing. Set artifacts: true (or list the producer in dependencies:) so the files transfer.
How do I confirm the producer actually uploaded artifacts?
Open the producing job in the UI and click Browse under its artifacts. If the panel is empty, the producer has no artifacts:paths; if it shows an expiry that has passed, increase expire_in.
Can I avoid downloading artifacts I do not need?
Yes. Use dependencies: [] to fetch none, or list only the producers you actually consume. This also speeds up jobs by skipping unnecessary downloads — just never omit a producer whose files the script truly requires.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.