Skip to content
Latchkey

Docker buildx "failed to solve: cannot reuse body" in CI

When BuildKit pushes or pulls and the registry answers with a redirect or auth challenge, the HTTP client must replay the original request body. If the body stream cannot be rewound, the transfer fails with "cannot reuse body, request must be retried". This is a transport-level retry condition, not a Dockerfile bug.

What this error means

A docker buildx build --push (or a pull) fails with failed to solve: cannot reuse body, request must be retried, often after a 307/401 from the registry. A retry usually succeeds.

docker
ERROR: failed to solve: cannot reuse body, request must be retried

Common causes

A redirect or auth challenge mid-upload

The registry redirected the blob upload or asked for re-auth, and the request body could not be replayed.

A proxy that strips or rewrites requests

A corporate proxy in front of the registry can force a retry the client cannot satisfy.

A stale credential refreshed mid-request

A token that expired and was refreshed forces a replay of the in-flight request.

How to fix it

Retry the push

  1. This is a transient transport condition - retry the build/push once.
  2. Refresh registry credentials right before the push so no mid-flight re-auth is needed.
Terminal
echo "$REGISTRY_TOKEN" | docker login ghcr.io -u "$REGISTRY_USER" --password-stdin
docker buildx build --push -t ghcr.io/myorg/app:ci .

Bypass a body-rewriting proxy

  1. If a proxy forces the retry, point the registry traffic around it or add it to NO_PROXY.
Terminal
export NO_PROXY=ghcr.io,registry.example.com
docker buildx build --push -t ghcr.io/myorg/app:ci .

How to prevent it

  • Log in to the registry immediately before pushing to avoid mid-request re-auth.
  • Exclude trusted registries from intercepting proxies.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →