Intro
Docker error messages can look cryptic, but most boil down to a few repeatable causes. This guide maps the most common errors to clear root causes, gives you exact commands to diagnose them, and shows safe fixes that you can verify locally before wider rollout.
Who this is for:
- Developers shipping services in containers
- DevOps consultants standardizing troubleshooting
- Technical startup teams building reliable delivery pipelines
What you get:
- A repeatable workflow for faster diagnosis
- Practical fixes for build, run, network, volume, and registry issues
- A small, local pilot plan to lock in wins before scaling
Workflow Overview
Use this flow to cut through noise and reduce rework:
- Reproduce exactly
- Capture the full command and versions:
- docker --version
- docker compose version
- docker info (redact secrets)
- Re-run with full logs:
- docker build --progress=plain .
- docker run --rm -it image: tag command
- Read the whole error
- Many Docker errors show a short summary followed by the real cause a few lines below. Scroll up.
- Minimize the scenario
- Replace your app with a tiny repro:
- Use a 5-line Dockerfile and a single COPY or RUN to isolate the failing step.
- Diff configuration
- Check Dockerfile stage by stage.
- Inspect Compose overrides and env files.
- Compare working vs failing tags, platforms, and mounts.
- Apply the smallest safe fix
- Prefer changing config over code if the problem is path, permissions, or platform.
- Verify locally
- Test in a clean environment:
- docker system prune -f (optional, beware this removes unused resources)
- docker build --no-cache .
- docker run --rm image: tag
Common Build Errors
1) COPY failed: file not found in build context
Symptoms:
- Example: COPY failed: file not found in build context or excluded by .dockerignore
Why it happens:
- The target path is outside the build context (the dot path you pass to docker build).
- .dockerignore excludes the file.
Fix:
- Build from the correct context directory and adjust paths.
- Update .dockerignore to keep needed files.
Example:
# Wrong (building from parent, but expecting app/ files)
docker build -t myapp .
# Right: build with app/ as context
docker build -t myapp ./app
# Review .dockerignore and remove patterns that hide required files
2) exec format error (architecture mismatch)
Symptoms:
- Standard_init_linux.go... exec format error
- Image runs on one machine but not on another (e.g., ARM laptop vs AMD64 server)
Why it happens:
- Image platform differs from the host or target node.
Fix:
- Build or pull for the right platform.
Examples:
# Force platform when building or running
DOCKER_BUILDKIT=1 docker build --platform=linux/amd64 -t myapp: amd64 .
docker run --rm --platform=linux/amd64 myapp: amd64
# Or use a multi-arch base image (e.g., python:3.11-slim) and let BuildKit create a matching image
3) no space left on device
Symptoms:
- Build fails writing layers or during apt-get install.
Why it happens:
- Local Docker data (images, layers, build cache) filled the disk.
Fix:
# See disk usage
docker system df
# Remove dangling/unused data (caution: frees space globally)
docker system prune -f
# Also remove unused images and volumes if safe
docker image prune -a -f
docker volume prune -f
4) RUN command fails due to shell or line endings
Symptoms:
- /bin/sh: 1: script.sh: not found
- exec user process caused: no such file or directory
Why it happens:
- Windows CRLF line endings in scripts.
- Missing executable bit or wrong shebang.
Fix:
# Normalize to LF on commit
git config core.autocrlf input
# Or convert files
apt-get update && apt-get install -y dos2unix && dos2unix script.sh
# Ensure executable and valid shebang
chmod +x script.sh
sed -n '1p' script.sh # should start with #!/bin/sh or #!/usr/bin/env bash
5) Build cache confusion
Symptoms:
- Old dependencies persist; changes do not apply.
Fix:
# View full step output
DOCKER_BUILDKIT=1 docker build --progress=plain .
# Bypass cache when needed
docker build --no-cache .
Run and Compose Errors
1) Port is already allocated
Symptoms:
- Error starting userland proxy: listen tcp 0.0.0.0:80: bind: address already in use
Fix:
# Find conflicting process (Linux/macOS)
lsof -i :80
# Windows (PowerShell)
Get-NetTCPConnection -LocalPort 80 | Format-List
# Stop or remap the port
# docker run -p HOST:CONTAINER
docker run -p 8080:80 nginx: alpine
# In compose.yml
services:
web:
image: nginx: alpine
ports:
- "8080:80"
2) exec user process caused: no such file or directory
Symptoms:
- Happens immediately on container start.
Why it happens:
- Entrypoint or CMD refers to a non-existent file or has CRLF line endings.
Fix:
# Inspect image
docker run --rm -it --entrypoint sh myapp: tag -c 'ls -l /app && file /app/entrypoint.sh'
# Normalize line endings and permissions as shown in build fixes
3) OCI runtime create failed: permission denied
Why it happens:
- Volume mount permissions, rootless Docker limits, or SELinux denials on Linux.
Fix:
# On SELinux hosts, label bind mounts
# :z for shared, :Z for private labeling
-v /host/data:/data: Z
# Align container user with host files
# Example: run as host UID 1000 and chown volume
docker run -u 1000:1000 -v $PWD/data:/data myapp: tag
4) Network not found in Compose
Symptoms:
- network mynet declared as external, but could not be found
Fix:
# Create the network or make it internal to the project
docker network create mynet
# Or remove external: true and let Compose create it
Networking and DNS Errors
1) Temporary failure in name resolution
Symptoms:
- DNS lookup fails inside the container.
Why it happens:
- Host DNS cannot be reached, corporate proxy, or blocked outbound.
Fix:
# Test DNS inside container
docker run --rm busybox nslookup google.com || true
# Set explicit DNS for the container
docker run --rm --dns 8.8.8.8 busybox nslookup google.com
# Configure daemon-wide DNS (daemon.json), then restart Docker
{
"dns": ["8.8.8.8", "1.1.1.1"]
}
If behind a proxy, set HTTP_PROXY/HTTPS_PROXY/NO_PROXY in the Dockerfile build stage and runtime environment as needed.
2) Cannot pull: lookup registry-1.docker.io: no such host
Fix:
- Apply the same DNS steps above.
- Verify you can curl https://registry-1.docker.io from the host.
Volumes and Permissions Errors
1) Permission denied on bind mounts
Symptoms:
- App cannot read/write mounted files.
Why it happens:
- Host UID/GID mismatch with container user.
- SELinux labels blocking access.
Fix:
# Align UIDs or use a compatible user
docker run -u $(id -u):$(id -g) -v $PWD/data:/data myapp: tag
# On SELinux hosts
docker run -v $PWD/data:/data: Z myapp: tag
# Prefer named volumes for portable writes
volumes:
data:
services:
app:
volumes:
- data:/data
2) File sharing not enabled (macOS/Windows)
Symptoms:
- Mount fails or directory is empty in container.
Fix:
- Enable file sharing for the drive/folder in Docker Desktop settings.
Images and Registry Errors
1) pull access denied, repository does not exist or may require authorization
Fix:
# Check the exact image name and tag
docker pull registry.example.com/team/app:1.2.3
# Log in to the registry
docker login registry.example.com
2) manifest unknown or not found
Why it happens:
- Tag does not exist or the manifest for your platform is missing.
Fix:
# List available tags (if your registry UI or API allows). Otherwise, confirm the tag in your release process.
# Pull with explicit platform if a multi-arch manifest exists
docker pull --platform linux/amd64 image: tag
3) Rate limit exceeded (public registries)
Fix:
- Authenticate to increase limits.
- Use a mirror or private registry cache where possible.
Performance and Resource Errors
1) OOMKilled or memory pressure
Symptoms:
- Container exits unexpectedly; logs show OOMKilled.
Fix:
# Constrain and observe
# Compose v2 example
services:
app:
image: myapp: tag
deploy:
resources:
limits:
memory: 512M
# Or docker run flags
docker run --memory=512m myapp: tag
Tune app memory usage or raise limits as needed.
2) Slow builds due to cache misses
Fix:
- Reorder Dockerfile so the most static steps (install OS deps) come before COPY of app code, to maximize cache reuse.
Local Pilot Plan
Start with a narrow, measurable pilot that runs fully on a developer laptop and is easy to inspect.
Goal
- Prove that common errors are caught and fixed quickly on a single service.
Scope
- One Dockerfile (e.g., a minimal Nginx or Python service).
- One compose.yml exposing an HTTP port and a writable data directory.
Steps
- Create a tiny service
# Dockerfile
FROM nginx: alpine
COPY ./public /usr/share/nginx/html
- Add common failure checks
- Remove a file from public and see COPY fail; fix by adjusting context and .dockerignore.
- Introduce CRLF in an entrypoint script; fix with LF and chmod +x.
- Force a platform mismatch; run with --platform to verify behavior.
- Bind mount a data dir; test permissions using user IDs and, on SELinux, :Z.
- Instrument quick diagnostics
# Makefile (optional convenience)
run:
docker compose up --build
shell:
docker run --rm -it --entrypoint sh myapp: dev
clean:
docker system prune -f
- Document exact fixes that worked
- Keep a short troubleshooting.md with error text, cause, and command used to fix.
- Extend gradually
- Add a second service (e.g., API) and a user-defined network.
- Add image pulls from a private registry to validate auth and tag handling.
This pilot is small, measurable, and easy to inspect locally, making it a safe way to standardize your approach before expanding to Kubernetes or CI/CD.
Conclusion
Most Docker problems repeat across projects: path and context mistakes, platform mismatches, DNS and proxy quirks, and permissions on mounts. With a simple, repeatable workflow and the fixes above, you can resolve issues quickly and safely. Start with the local pilot, record what works, and expand the same patterns to Docker Compose, Kubernetes, and your CI system.