# Docker Registry Push Failed: How to Push Images Successfully

You tried to push an image to a registry, but it failed:

bash
denied: requested access to the resource is denied

Or:

bash
Error response from daemon: manifest for myimage:latest does not exist

Or simply:

bash
unauthorized: authentication required

Pushing images to registries is essential for deployment. Let me show you how to diagnose and fix these failures.

Understanding Registry Push

  1. 1.Push requires:
  2. 2.Proper authentication
  3. 3.Correct image tagging (registry prefix)
  4. 4.Registry accessibility
  5. 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:

bash
# Using access token instead of password
echo "dckr_pat_xxxxx" | docker login -u myuser --password-stdin

Step 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:

bash
Error response from daemon: Get https://registry.local/v2/: http: server gave HTTP response to HTTPS client

Configure insecure registry:

json
// /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:

IssueSolution
Connection refusedRegistry down or wrong port
Certificate errorAdd to insecure-registries or get proper cert
TimeoutNetwork/firewall issue
DNS failureFix 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:

bash
manifest invalid: manifest blob digest mismatch

Fix:

```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

ErrorCauseFix
denied: access deniedNot logged indocker login REGISTRY
unauthorizedWrong credentialsCheck username/password
repository does not existWrong name/tagTag with correct prefix
manifest blob digest mismatchCorrupted layerRebuild and push
http server gave HTTP responseInsecure registryAdd to insecure-registries
Too Many RequestsRate limitedAuthenticate or wait

Best Practices

  1. 1.Always login first before pushing
  2. 2.Use consistent tagging strategy
  3. 3.Push to specific tags (not just latest)
  4. 4.Use proper registry URLs (with port if needed)
  5. 5.Clean up old images to save space
  6. 6.Document push process for team

Quick Reference

TaskCommand
Login to registrydocker login REGISTRY
Tag for registrydocker tag IMAGE REGISTRY/IMAGE:TAG
Push imagedocker push REGISTRY/IMAGE:TAG
Logoutdocker logout REGISTRY
Test registrycurl REGISTRY/v2/
List repositoriescurl 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.