Artifact expiration policy silently deletes downstream artifacts after pipeline completion
0 reputation · 08 May 2020, 07:02 UTC
0 reputation · 08 May 2020, 07:02 UTC
Maintain artifacts for downstream pipelines while respecting the configured expiration period.
GitLab allows expiration to be set globally, per-pipeline, or per-job. It is unclear whether artifacts referenced by downstream jobs are exempt from the same expiration rules or if they inherit the same policy as the originating job.
33275 reputation · 08 May 2020, 14:42 UTC
Yes — when an artifact reaches its expire_in deadline, GitLab deletes it regardless of whether downstream pipelines reference it. Expiration is a property of the artifact record created by the producing job, not of its consumers. A downstream pipeline using needs:pipeline or the artifacts download API gets no exemption; once the upstream artifact is purged, the fetch fails at runtime, which is why the deletion feels silent.
Confirmed behavior (well-established across recent GitLab versions):
expire_in on the producing job sets an expire_at timestamp on that job's artifacts. The expiry worker deletes them when that time passes.expire_in) or via instance/group/project maximum expiration policies, which can override job settings.expire_in on the producing job (or expire_in: never, accepting the storage cost and any instance-level maximum that may still apply).curl --request POST --header "PRIVATE-TOKEN: $TOKEN" \
"https://gitlab.example.com/api/v4/projects/$PROJECT_ID/jobs/$JOB_ID/artifacts/keep"
Yes, there is an API for this. The Jobs API exposes artifact metadata including expire_at:
curl --header "PRIVATE-TOKEN: $TOKEN" \
"https://gitlab.example.com/api/v4/projects/$PROJECT_ID/jobs/$JOB_ID" \
| jq '.artifacts[] | {filename, expire_at}'
You can poll this before triggering a downstream pipeline, or run it in a scheduled job to alert on artifacts nearing expiry.
To confirm this is actually your problem rather than a permissions or ref issue: set a short expire_in: 5 minutes on the producing job in a test branch, run the pipeline, wait, then trigger the downstream pipeline. If the artifact download step fails with a missing-artifact error, expiration is the cause. Also check your project and (if self-managed) admin CI/CD settings for the keep-latest-artifacts toggle and any maximum expiration override, since defaults differ between GitLab.com and self-managed instances and have changed across releases.
If downstream fetches fail before the expire_at timestamp shown by the API, share the exact error from the downstream job log — that would point to a different cause (ref mismatch, pipeline source, or permissions) and change the recommendation.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.