Safeguard
Developer Tools•

How does Docker registry garbage collection work, and is it safe?

Registry garbage collection marks referenced blobs, then sweeps the rest. It is stop the world, so put the registry in read-only mode before running it.

Safeguard Security Team
4 min read

Registry garbage collection removes blobs that no manifest references. It runs in two phases, mark then sweep, and it is stop the world. The docs say the registry should be read only or not running while it works, because an upload during collection could lose layers and corrupt an image.

The two phases

Layers are stored by content address and shared between manifests. The collector works like this.

  1. Mark. It scans every manifest and builds the set of digests to keep.
  2. Sweep. It scans every blob and deletes any whose digest is not in that set.

Deleting a manifest through the API only removes the reference. The blobs remain until a sweep. The docs give an example with manifest A using layers a and b, and manifest B using layers a and c. Delete B and layer c becomes eligible, while layer a stays because A still uses it.

The command

bin/registry garbage-collect [--dry-run] [--delete-untagged] [--quiet] /path/to/config.yml
  • --dry-run shows mark and sweep progress without deleting anything. Set the log level to info to see what is eligible.
  • --delete-untagged also removes manifests that no tag points to.
  • --quiet suppresses output.

The config file must define a storage driver. The command has been in the registry binary since v2.4.0.

Why writes must stop

Think about a push that arrives mid run. The collector has already built its keep set. A new image uploads layers that no stored manifest references yet. The sweep sees unreferenced blobs and deletes them. The manifest then lands pointing at layers that are gone. Later pulls fail or, worse, produce a broken image.

That is why the guide says the registry should be in read only mode or not running at all.

A safe procedure

  1. Confirm delete is enabled and that you have a backup of storage.
  2. Announce a window. CI jobs that push will fail during it.
  3. Set storage.maintenance.readonly.enabled to true and restart, so clients cannot write.
  4. Run the command with --dry-run and read what would go.
  5. Run it for real.
  6. Turn read only mode off and restart.
  7. Pull a few known images by digest to confirm they are intact.

Be careful with --delete-untagged. Images referenced only by digest, for example in a deployment manifest, have no tag. Deleting untagged manifests removes them.

Does this affect security?

Yes, in two ways. Stale images carry known vulnerabilities, so removing them shrinks what an attacker can pull. But collection also removes evidence you may want after an incident, so keep the images of released versions and log what you delete.

Safeguard can scan container images and report what is inside the ones you keep. A free scan is at gold.safeguard.sh/scan.

Try it yourself

Click through it at your own pace, or open it full screen.

Click through the demo and watch how a result ties back to a specific artifact, which is what you want from any registry you run.

Quick check

Can I run garbage collection while developers push?

No. The docs say the registry should be read only or stopped, because an upload during collection could have its layers deleted.

Does a dry run delete anything?

No. It prints mark and sweep progress without removing data.

Why did disk usage not drop after I deleted images?

API deletes remove references only. Space is freed when the sweep runs, and shared layers stay while another manifest uses them.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.