Docker Error Guide: 'blob upload unknown' — Fix Failed Image Pushes
Fix Docker 'blob upload unknown' on push: resolve interrupted chunked uploads, load balancer session affinity, proxy body limits, and registry storage issues so docker push completes.
- #docker
- #troubleshooting
- #errors
- #registry
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
blob upload unknown (registry error code BLOB_UPLOAD_UNKNOWN) occurs during docker push. Pushing a layer is a multi-request handshake: the client opens an upload session, the registry returns a session URL, and the client streams (or chunks) the blob to that URL and finalizes it. This error means the registry no longer recognizes the upload session the client is referencing — the session was lost, expired, or routed to a different backend than the one that created it.
The literal error appears mid-push:
docker push myregistry.example.com/app:2.1.0
The push refers to repository [myregistry.example.com/app]
b1a2c3d4: Pushing [==============> ] 128.4MB/210MB
blob upload unknown: blob upload unknown to registry
Symptoms
docker pushfails partway withblob upload unknown, often on larger layers.- Small images push fine; large layers that take longer to upload fail — a sign of session timeout or LB affinity loss.
- Failures are intermittent and load-dependent (behind a load balancer or autoscaled registry).
- Retrying the push sometimes succeeds because a new session is opened.
Common Root Causes
- Load balancer without session affinity — a multi-replica registry behind an LB routes the finalize request to a different backend that never saw the upload session (especially with local filesystem storage instead of shared object storage).
- Upload session timeout — a slow upload exceeds the registry’s session TTL, so the session is garbage-collected before finalize.
- Reverse-proxy body/size limits — nginx/traefik
client_max_body_size, request timeouts, or buffering limits truncating or dropping the upload. - Registry storage backend errors — the registry cannot persist the in-progress upload (permissions, full disk, misconfigured S3/GCS bucket).
- Network interruption mid-upload dropping the chunked session.
- Clock skew / expired auth token invalidating the session before finalize.
Diagnostic Workflow
Confirm the pattern — is it only large or slow layers?
docker push <registry>/<repo>:<tag> 2>&1 | tee push.log
grep -i 'blob upload unknown' push.log
If you run the registry, read its logs for the failing upload UUID and backend that handled it:
docker logs <registry-container> 2>&1 | grep -i 'upload\|blob\|error'
journalctl -u registry --since '10 min ago' | grep -iE 'upload|timeout|storage'
Check the reverse proxy for size/timeout limits and buffering (nginx example):
grep -iE 'client_max_body_size|proxy_read_timeout|proxy_request_buffering' /etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf
Verify load balancer affinity and shared storage for multi-replica registries:
# Are multiple registry replicas sharing the SAME object-storage backend?
kubectl get deploy,svc -n registry 2>/dev/null
# Registry config should point storage at S3/GCS/Azure, not local filesystem, when replicated
Test with a single-shot (non-chunked) push and fresh login to rule out token expiry:
docker logout <registry>; docker login <registry>
docker push <registry>/<repo>:<tag>
Example Root Cause Analysis
A team’s self-hosted registry, recently scaled from one to three replicas behind a Kubernetes Service, began failing pushes of large images with blob upload unknown, while small images pushed fine. The registry replicas were each using local filesystem storage with no shared backend, and the Service load-balanced requests round-robin. A layer upload started on replica A, but the finalize request landed on replica B, which had no record of that upload session — hence “upload unknown.”
The fix was to configure all three replicas to use a shared S3 object-storage backend (the registry’s storage.s3 config) instead of local disk, so any replica could complete any session. As a defensive measure they also enabled session affinity on the Service. After pointing storage at the shared bucket, large pushes completed regardless of which replica handled each request.
Prevention Best Practices
- Use shared object storage (S3/GCS/Azure) for replicated registries, never per-replica local filesystem, so any backend can finalize any upload.
- Enable session affinity on the load balancer as a second line of defense.
- Raise proxy limits: set generous
client_max_body_size, read/send timeouts, and disable request buffering for the registry path. - Tune upload session TTL on the registry to comfortably exceed the time large layers take on your slowest links.
- Keep image layers small so uploads finish well within session and timeout windows.
- Retry pushes with backoff in CI to absorb transient session drops.
Quick Command Reference
docker push <registry>/<repo>:<tag> # reproduce, note which layer fails
docker logs <registry-container> | grep -i upload # registry-side session detail
grep -i client_max_body_size /etc/nginx/conf.d/* # proxy body limit
docker logout <registry> && docker login <registry> # refresh auth/session
# registry config: storage backend -> shared s3/gcs, not local filesystem
Conclusion
blob upload unknown means the registry lost the upload session the push is trying to finalize — almost always a routing or lifetime problem, not a bad image. For replicated registries, the fix is shared object storage plus load-balancer affinity; for proxied ones, raise body and timeout limits; for slow links, extend the session TTL and keep layers small. Confirm by checking whether only large, slow layers fail. For pull-side blob failures, see the error pulling image configuration guide and the full Docker guides.
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.