# Docker Registry Push Failed: How to Push Images Successfully
You tried to push an image to a registry, but it failed:
denied: requested access to the resource is deniedOr:
Error response from daemon: manifest for myimage:latest does not existOr simply:
unauthorized: authentication requiredPushing images to registries is essential for deployment. Let me show you how to diagnose and fix these failures.
Understanding Registry Push
- 1.Push requires:
- 2.Proper authentication
- 3.Correct image tagging (registry prefix)
- 4.Registry accessibility
- 5.Repository permissions
Step 1: Authenticate to the Registry
The most common cause is authentication:
```bash # Login to Docker Hub docker login
# Login with username docker login -u myusername
# Login to private registry docker login registry.example.com
# Login with password from stdin (for scripts) echo "mypassword" | docker login -u myuser --password-stdin
# Logout docker logout registry.example.com ```
Verify login status:
```bash # Check credentials cat ~/.docker/config.json
# Check logged-in user (Docker Hub) docker info | grep Username ```
Docker Hub token login:
# Using access token instead of password
echo "dckr_pat_xxxxx" | docker login -u myuser --password-stdinStep 2: Tag Images Correctly
Images must be tagged with the registry prefix:
```bash # Wrong: no registry prefix (tries Docker Hub) docker push myimage:latest # May fail if repo name doesn't match your Docker Hub username
# Correct: include Docker Hub username docker tag myimage:latest myuser/myimage:latest docker push myuser/myimage:latest
# For private registry docker tag myimage:latest registry.example.com/team/myimage:latest docker push registry.example.com/team/myimage:latest ```
Tagging workflow:
```bash # Build image docker build -t myapp:latest .
# Tag for registry docker tag myapp:latest registry.example.com/myapp:v1.0
# Push docker push registry.example.com/myapp:v1.0 ```
Step 3: Check Repository Permissions
For Docker Hub, repository naming matters:
```bash # Docker Hub requires: USERNAME/REPOSITORY # If your username is "devteam", push to: docker push devteam/myimage:latest
# Organization repositories docker push myorg/myimage:latest # You must have write access to the org ```
For private registries:
Check your permissions: - Are you in the right team/project? - Does the repository exist? - Do you have write permission?
Step 4: Handle Insecure Registries
Self-hosted registries without TLS cause errors:
Error response from daemon: Get https://registry.local/v2/: http: server gave HTTP response to HTTPS clientConfigure insecure registry:
// /etc/docker/daemon.json
{
"insecure-registries": ["registry.local", "192.168.1.100:5000"]
}```bash # Restart Docker sudo systemctl restart docker
# Now push works docker push registry.local/myimage:latest ```
Step 5: Test Registry Connectivity
Verify the registry is accessible:
```bash # Test registry API curl -v https://registry.example.com/v2/
# For insecure registry curl -v http://registry.local:5000/v2/
# Test with authentication curl -v -u user:pass https://registry.example.com/v2/
# Check DNS resolution nslookup registry.example.com ```
Common connectivity issues:
| Issue | Solution |
|---|---|
| Connection refused | Registry down or wrong port |
| Certificate error | Add to insecure-registries or get proper cert |
| Timeout | Network/firewall issue |
| DNS failure | Fix DNS or use IP |
Step 6: Handle Large Image Pushes
Large images may timeout or fail:
```bash # Check image size docker images myimage:latest
# Enable layer sharing docker push --disable-content-trust registry.example.com/myimage:latest
# For very large images, increase client timeout # In daemon.json: { "max-concurrent-downloads": 1, "max-concurrent-uploads": 1 } ```
Reduce image size:
```dockerfile # Use smaller base images FROM alpine:latest # Instead of ubuntu
# Combine RUN commands RUN apt-get update && apt-get install -y packages && apt-get clean
# Use multi-stage builds FROM builder AS build # Build artifacts
FROM alpine COPY --from=build /artifacts /app ```
Step 7: Debug Push Failures
Enable verbose output:
```bash # Debug registry operations DOCKER_DEBUG=1 docker push registry.example.com/myimage:latest
# Check daemon logs journalctl -u docker.service | grep -i push
# Test specific layer push docker push registry.example.com/myimage:latest 2>&1 | tee push.log ```
Check manifest:
```bash # Inspect image manifest docker inspect myimage:latest --format '{{json .}}'
# Check registry manifest after push curl -H "Authorization: Bearer TOKEN" \ https://registry.example.com/v2/myimage/manifests/latest ```
Step 8: Handle Existing Repository Conflicts
Pushing to existing repos may conflict:
manifest invalid: manifest blob digest mismatchFix:
```bash # Force push by deleting remote first # (Registry API, or UI) # Then push fresh docker push registry.example.com/myimage:latest
# Or use different tag docker tag myimage:latest registry.example.com/myimage:v2 docker push registry.example.com/myimage:v2 ```
Step 9: Registry-Specific Issues
Docker Hub rate limits:
```bash # Error: toomanyrequests: Too Many Requests # Solution: authenticate or wait
docker login # Authenticated requests have higher limits
# Or use mirror registry docker pull registry.docker-cn.com/library/nginx ```
AWS ECR:
```bash # Login to ECR aws ecr get-login-password --region us-east-1 | \ docker login --username AWS --password-stdin ACCOUNT.dkr.ecr.us-east-1.amazonaws.com
# Create repository first aws ecr create-repository --repository-name myimage
# Push docker push ACCOUNT.dkr.ecr.us-east-1.amazonaws.com/myimage:latest ```
Google GCR:
```bash # Configure gcloud gcloud auth configure-docker
# Push docker push gcr.io/PROJECT_ID/myimage:latest ```
Azure ACR:
```bash # Login az acr login --name myregistry
# Push docker push myregistry.azurecr.io/myimage:latest ```
Step 10: Verify Push Success
After pushing, verify:
```bash # Pull the pushed image docker pull registry.example.com/myimage:latest
# Check registry catalog curl -s https://registry.example.com/v2/_catalog | jq
# Check tags curl -s https://registry.example.com/v2/myimage/tags/list | jq
# Docker Hub: check via web UI # https://hub.docker.com/r/myuser/myimage ```
Complete Push Workflow
```bash # 1. Build image docker build -t myapp:v1.0 .
# 2. Login to registry docker login registry.example.com
# 3. Tag for registry docker tag myapp:v1.0 registry.example.com/team/myapp:v1.0
# 4. Verify tagging docker images | grep registry.example.com
# 5. Push docker push registry.example.com/team/myapp:v1.0
# 6. Verify docker pull registry.example.com/team/myapp:v1.0
# 7. Logout if needed docker logout registry.example.com ```
Common Push Error Patterns
| Error | Cause | Fix |
|---|---|---|
denied: access denied | Not logged in | docker login REGISTRY |
unauthorized | Wrong credentials | Check username/password |
repository does not exist | Wrong name/tag | Tag with correct prefix |
manifest blob digest mismatch | Corrupted layer | Rebuild and push |
http server gave HTTP response | Insecure registry | Add to insecure-registries |
Too Many Requests | Rate limited | Authenticate or wait |
Best Practices
- 1.Always login first before pushing
- 2.Use consistent tagging strategy
- 3.Push to specific tags (not just
latest) - 4.Use proper registry URLs (with port if needed)
- 5.Clean up old images to save space
- 6.Document push process for team
Quick Reference
| Task | Command |
|---|---|
| Login to registry | docker login REGISTRY |
| Tag for registry | docker tag IMAGE REGISTRY/IMAGE:TAG |
| Push image | docker push REGISTRY/IMAGE:TAG |
| Logout | docker logout REGISTRY |
| Test registry | curl REGISTRY/v2/ |
| List repositories | curl REGISTRY/v2/_catalog |
Registry push failures are usually authentication or tagging issues. Login first, tag with the correct registry prefix, and ensure the repository exists.