Quick answer

What this guide helps you do

Diagnose Docker Engine 29.7 image-pull and docker cp regressions, update safely to 29.7.2 or later, and verify Compose, volumes and media containers.

Quick answer

If image pulls or docker cp started failing immediately after a Docker Engine 29.7 update, check the exact Engine version before changing the container or deleting Docker data.

Docker Engine 29.7.0 introduced regressions that were repaired across 29.7.1 and 29.7.2. The documented failures include:

  • image layers containing directories without explicit parent-directory entries
  • container paths that traverse absolute symbolic links
  • images containing absolute hardlink targets
  • permission application on older Linux kernels, including device nodes
  • some nftables compatibility problems

Update the complete Docker package set from the same official repository to 29.7.2 or a later supported patch, restart Docker, retry the isolated pull, and then recreate only the affected Compose service.

Do not delete /var/lib/docker, remove volumes or run a broad prune. Those actions do not repair an Engine regression and can destroy useful data or rollback evidence.


Was the Docker update actually the cause?

Version timing is evidence, but it is not proof. Capture the error before changing anything:

docker version
docker compose version
docker info
sudo journalctl -u docker --since '-30 minutes' --no-pager

Record the failed command exactly:

Command:
Full error:
Engine client version:
Engine server version:
Ubuntu version and kernel:
Image:
Registry:
Time failure started:
Last Docker package update:

Check recent Apt activity:

grep -E 'docker|containerd|buildx|compose' /var/log/apt/history.log
uname -a
cat /etc/os-release

If the failure began directly after 29.7.0 or 29.7.1 arrived, the documented regression is a strong suspect. If the server still runs Docker 28 or another branch, use the exact release notes for that version instead.


Match the symptom to the 29.7 fixes

SymptomRelevant fix
Pull fails on an image layer with an unusual directory layout29.7.1 repaired layers with missing explicit parent-directory entries
docker cp or an API copy fails where a path crosses /var/run to /run or another absolute symlink29.7.1 repaired absolute-symlink path handling
Pull rejects an image containing an absolute hardlink target29.7.2 repaired the 29.7.0 regression
Pull or docker cp fails while applying permissions on an older kernel29.7.2 repaired the 29.7.0 regression, including device-node cases
nftables rules fail to load on some releases29.7.2 improved syntax compatibility

These are Engine-side fixes. Rewriting a working Compose file, changing the container user or recursively changing media permissions is unlikely to help when the same image and deployment worked before the Engine update.


Step 1: confirm the Engine server version

docker version displays both client and server information. The server version is the important value for daemon-side pulls and extraction.

For a compact result:

docker version --format 'client={{.Client.Version}} server={{.Server.Version}}'

Also record the installed package set and repository candidate:

dpkg-query -W 'docker-ce' 'docker-ce-cli' 'containerd.io' \
  'docker-buildx-plugin' 'docker-compose-plugin' 2>/dev/null

apt-cache policy docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

Do not assume the CLI and daemon were updated together. A remote Docker context can also make the CLI talk to a different server:

docker context show
docker context ls

Step 2: preserve the failure evidence

Retry the smallest failing operation once and save the complete output:

docker pull repository/image:tag 2>&1 | tee docker-pull-error.txt

Replace the image reference with the one that failed. Do not include private registry credentials or tokens in a public report.

Collect the daemon log around the attempt:

sudo journalctl -u docker --since '-10 minutes' --no-pager \
  > docker-daemon-error.txt

If the image is private, test a public image only when doing so fits the host’s security and change policy. A successful unrelated pull does not rule out a layer-layout regression affecting one particular image.

Step 3: check the host before updating

Confirm Docker is otherwise healthy:

systemctl status docker --no-pager
systemctl --failed
df -hT
df -ih
docker system df
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'

Low disk space, exhausted inodes, DNS failures and registry authentication errors can look like update problems.

Useful distinctions:

Error typeFirst place to investigate
no space left on deviceDisk space, inodes and Docker storage
unauthorized or deniedRegistry credentials and repository access
timeout or name-resolution failureDNS, routing, firewall and registry availability
manifest does not match platformImage architecture and tag
hardlink, symlink, parent directory or permission-application failure after 29.7.0Docker 29.7 regression and patch level

Do not prune images merely because docker system df reports reclaimable space. First prove that capacity is the failure.

Step 4: protect Compose and persistent data

Before updating Docker packages, save the deployment information needed to recover applications.

For each important Compose project:

cd /path/to/compose-project
docker compose config > compose-effective-before-docker-fix.yaml
docker compose config --images
docker compose ps

Back up:

  • Compose files
  • .env files and secrets using protected storage
  • bind-mounted configuration and application data
  • named-volume data using the application’s supported method
  • database exports where required
  • /etc/docker/daemon.json, if it exists
  • current container, network and volume inventories

Use How to Back Up and Restore Docker Compose Services for the complete recovery design.

Step 5: confirm all Docker packages come from one source

On an Ubuntu host installed from Docker’s official Apt repository:

apt-cache policy docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

The package origin and candidate versions should make sense as one supported set. Do not mix Ubuntu’s docker.io package with selected docker-ce components from Docker’s repository.

Preview the repair update:

sudo apt update
sudo apt-get --simulate install docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

Stop if Apt proposes removing important packages, switching package families or installing an unexpected version.

Step 6: update to the repaired patch

For Docker’s official Ubuntu package installation:

sudo apt install docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

Read the proposed transaction before accepting it. The command installs the newest version currently offered by the configured repository; verify that the candidate is 29.7.2 or a later supported patch before proceeding.

Updating these packages normally restarts the Docker daemon. Schedule a maintenance window and confirm you have SSH or console access that does not depend on a container.

If the server intentionally pins package versions, review and document the pin rather than removing it blindly.

Step 7: verify Docker before recreating containers

After the package update:

systemctl status docker --no-pager
docker version
docker compose version
docker info
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
sudo journalctl -u docker --since '-15 minutes' --no-pager

Confirm:

  • the server reports 29.7.2 or a later intended patch
  • the daemon is active
  • expected containers returned
  • health checks settle
  • existing networks and volumes remain present
  • no repeated storage-driver, firewall or permission error appears

Do not refresh every container image during this check. Keep the application layer unchanged until the Engine is healthy.

Step 8: retry the isolated image pull

Retry the original image:

docker pull repository/image:tag

If it succeeds, record the new image ID:

docker image inspect repository/image:tag \
  --format 'id={{.Id}} created={{.Created}}'

If it still fails, compare the full new error with the saved pre-update result. Do not assume every image-pull failure is the same regression.

Check:

  • registry authentication
  • DNS and TLS errors
  • available disk space and inodes
  • proxy settings
  • image architecture
  • daemon storage-driver errors
  • whether the host really contacted the updated daemon context

Step 9: recreate only the affected Compose service

Once the pull succeeds, recreate the intended service rather than the entire stack:

cd /path/to/compose-project
docker compose up -d service-name
docker compose ps service-name
docker compose logs --timestamps --tail=200 service-name

Replace service-name with the Compose service name.

Avoid:

docker compose pull
docker compose up -d

against a large stack when those commands would update several unrelated applications. Change one service and make the result attributable.

Step 10: verify volumes, networks and media services

Inspect the recreated container:

SERVICE_CONTAINER_ID=$(docker compose ps -q service-name)
docker inspect "$SERVICE_CONTAINER_ID" --format '{{json .Mounts}}'
docker inspect "$SERVICE_CONTAINER_ID" --format '{{json .NetworkSettings.Networks}}'
docker inspect "$SERVICE_CONTAINER_ID" --format '{{json .HostConfig.RestartPolicy}}'

For a typical media stack, test separately:

  • Jellyfin login, library visibility and one playback session
  • Jellyfin bind mounts and hardware devices
  • Sonarr and Radarr access to downloads and library paths
  • download-client connectivity
  • DNS between Compose services
  • published ports from the local network
  • health checks and recent logs

If Jellyfin starts but cannot see media, do not blame the image pull automatically. Check Jellyfin Docker Volume Paths Explained, Jellyfin Docker Permissions and Jellyfin Library Not Showing Files.


What not to do

Do not respond to this regression by:

  • deleting /var/lib/docker
  • deleting named volumes
  • running docker system prune -a --volumes
  • recursively changing media ownership or permissions
  • rebuilding the whole Ubuntu server
  • changing the Compose network design
  • updating every application image simultaneously
  • repeatedly restarting Docker without preserving logs

Those actions expand the failure and remove evidence. Repair the Engine patch level first, then re-test the same operation.


If you cannot update immediately

There is no universal safe workaround for every 29.7 regression.

Keep the affected service unchanged if its existing container is still healthy. Avoid removing the working container or image until the repaired Engine is available and the deployment has been backed up.

Do not rebuild an image, rewrite its filesystem layout or weaken host permissions merely to work around a daemon bug unless you fully control the image and have tested the change.

Downgrading Docker is also a maintenance operation. It depends on the previous packages still being available and compatible with the current daemon state. Preserve logs and inventories, then follow Docker’s release-specific guidance rather than forcing an arbitrary package version.


Official sources



Recap

Docker Engine 29.7.0 introduced several image extraction and copy regressions. Docker repaired them across 29.7.1 and 29.7.2.

Capture the exact failure, confirm the daemon version, protect Compose and persistent data, update the complete Docker package set to 29.7.2 or a later supported patch, and retry the isolated pull. Recreate and verify only the affected service after the Engine itself is healthy.