Sometimes, and you should not count on it. GitHub documents that a deleted package or version can be restored within 30 days if its namespace is still free. Azure Container Registry states that deleted image data is unrecoverable. Assume a rebuild from source is your real recovery plan.
What the documentation says
| Registry | Restore position in its docs |
|---|---|
| GitHub Packages | Restore a package or version within 30 days of deletion, if the same package namespace is still available and unused |
| Azure Container Registry | Warns that deleted image data is unrecoverable, in both the retention and purge pages |
| Amazon ECR | The pages reviewed here describe expiry and archive, with no restore after expiry stated. Check the current documentation before relying on it |
| Google Artifact Registry | The cleanup policy page describes deletion and dry runs, with no restore stated. Check before relying on it |
For ECR there is an archive stage. An image archived and later restored is mentioned in the lifecycle rules, since the last activated time is used for restored images. That is a different thing from recovering an expired image.
Why a rebuild must work
If restore is unreliable, the safety net is the ability to produce the same image again. That depends on a few habits:
- Source is tagged at release, so you can find the exact commit.
- Base images and dependencies are pinned, so the rebuild matches. See pin base images by digest for repeatable rebuilds.
- Build steps are scripted and run in CI, not on a laptop.
- You record the digest of what shipped, so you can tell a rebuild apart from the original.
A rebuild is rarely bit for bit identical unless you work for it. See reproducible container builds, SOURCE_DATE_EPOCH explained. For most teams a functionally equivalent rebuild is enough, as long as you record that it is a rebuild.
Reduce the need to restore
- Run a preview or dry run before enabling any rule.
- Protect release images with a lock or immutability setting.
- Use a mark then wait approach before deletion.
- Narrow delete rights to a small set of identities and automation.
See lock, protect or immutable and a registry cleanup dry run checklist.
If something critical was deleted
Check the registry documentation for a restore path and act inside any window, such as GitHub's 30 days. Look for copies in mirrors, pull through caches, node caches and build caches. In parallel, start a rebuild from the tagged source. Record what you did in your incident notes.
Practise the recovery once
Pick a low risk service and rebuild its image from the tagged source in a clean environment. Time it, note what was missing, and fix the gaps. The first rebuild nearly always finds an unpinned base image, a build step that needs a laptop, or a secret that only one person knows. Finding these in practice is far better than finding them during an outage.
Quick check
Is the 30 day GitHub window universal?
No. It is GitHub's documented rule for packages. Other registries differ, and Azure says deleted data is unrecoverable.
Can a node cache save me?
It might, if a node still holds the image. Treat that as luck, not a plan, and rebuild properly.
Sources
- Deleting and restoring a package, GitHub Docs
- Azure Container Registry retention for untagged manifests
- Amazon ECR lifecycle policies
- Artifact Registry cleanup policies
Last reviewed: 19 October 2026.