maborak.com~/blog/docker-engine-29-image-storesoftware & infrastructure engineering
Back to all articles

Docker Engine 29: the image store changed under you

Engine 29 makes the containerd image store the default for new installs, bumps the API, and its 29.9.x line carries a long list of security fixes.

By the Maborak engineering team · · 4 min read

Docker Engine 29 is a foundation release, not a patch. It changes the default image store for new installations, moves the Engine API, and accumulates fixes for a steady stream of CVEs through the 29.9.x line. A host upgraded by package manager can end up with a different storage layout than the one its backup, prune and build scripts were written for.

Checked 29 October 2026. Version dates and CVE identifiers are from the Engine 29 release notes. The default-image-store change is from Docker’s own 29 announcement.

Background

The classic image store kept layers under the graph driver (overlay2 and others) with Docker’s own metadata. The containerd image store delegates image and snapshot management to containerd, which is also what allows multi-platform images in a single local store. Engine 29 makes it the default for new installations. Existing installations can keep the old store, but the two are not interchangeable in place.

Security releases in the window:

  • 29.5.0: CVE-2026-32288, unbounded memory on a crafted sparse tar image.
  • 29.5.1: CVE-2026-41567, CVE-2026-41568, CVE-2026-42306, docker cp path and privilege issues.
  • 29.7.0: CVE-2026-17106, archive path handling.
  • 29.8.2: a batch across Engine and BuildKit, including registry DNS handling (CVE-2026-92543).
  • 29.9.0: HTTP/2 denial-of-service fixes in the Go runtime.
  • 29.9.1: containerd transfer and image-pull fixes.
  • 29.9.2: CVE-2026-111943, revoked eMudhra intermediate certificates; pulls fail if a registry chain depends on them.

Mechanics

The store decides where layers live, how docker image ls counts size, what docker system df reports, and what docker save writes. When the store changes, old images are not always visible in the new one, and a prune can reclaim different amounts than expected. The API version bump also matters to clients pinned to an older /v1.x version.

Impact

Three practical failures: disk accounting changes, so capacity alerts fire or stop firing; backup scripts that assume overlay2 paths break; and a registry whose TLS chain uses a revoked intermediate cannot be pulled at all after 29.9.2. The last one is a supply-chain control working as intended, and it looks like an outage if nobody checked the chain.

Probe

docker version --format 'server={{.Server.Version}} api={{.Server.APIVersion}}'
docker info --format 'driver={{.Driver}}'
docker info | sed -n '/Storage Driver/,+3p'
docker system df
docker image ls --format '{{.Repository}}:{{.Tag}} {{.ID}} {{.Size}}'

Compare the reported driver and the documented output for the store you intend to use. On a host with both stores, an image present in one is not necessarily visible in the other. Check the registry chain before a mass upgrade:

openssl s_client -connect registry.example:443 -servername registry.example </dev/null 2>/dev/null \
  | openssl crl2pkcs7 -nocrl -certfile /dev/stdin | openssl pkcs7 -print_certs -noout

The probe identifies the store, the API version and the size accounting. It does not migrate anything.

Mitigation

  • Upgrade to the current 29.9.x, not to 29.0. The 29.9.2 release notes list the fixed CVEs and the revoked intermediates.
  • Test the image-store change on a clone: pull the production images, run docker system df, save and load one image, and confirm the numbers your alerts use.
  • Pin the API version used by automation and read the version history before the daemon moves.
  • Keep the old store until the new one has served a full pull/build/push cycle. Switching back is not a flag toggle once images have been written in the new store.

Verification

docker version
docker run --rm hello-world
docker pull registry.example/image:tag
docker system df

A successful docker version only proves the daemon responded. The proof is a pull from each registry you use, a build that pushes, and a restore from the backup path your scripts actually take.

On the machine used for this check, the daemon reports server 29.5.2, API 1.54 and driver overlayfs. 29.5.2 predates the 29.9.2 fixes listed above, which is the gap the version probe is meant to expose. [reproduced]

Sources

Back to all articles

Technologies we work with

  • Argo CD
  • Kubernetes
  • Docker
  • Podman
  • Ansible
  • Jenkins
  • Chef
  • Proxmox VE
  • Google Cloud
  • Linux
  • Red Hat
  • CentOS
  • NGINX
  • Apache
  • Traefik
  • Prometheus
  • Grafana
  • PostgreSQL
  • MySQL
  • MariaDB
  • Redis
  • etcd
  • Qdrant
  • Elasticsearch
  • Logstash
  • Kibana
  • PagerDuty
  • Go
  • Python
  • FastAPI
  • PHP
  • TypeScript
  • React