This error occurs when Docker tries to pull images through a corporate proxy that requires authentication. The Docker daemon needs proper proxy credentials configured to access Docker Hub or other registries.
The "Proxy Authentication Required" error (HTTP 407) indicates that your Docker daemon is behind a proxy server that requires username and password authentication, and the credentials are either missing, incorrect, or not properly configured for Docker. When you run commands like `docker pull` or `docker login`, the Docker daemon attempts to connect to the container registry (e.g., registry-1.docker.io). If your network routes traffic through an authenticated proxy, the proxy intercepts the request and demands credentials before forwarding it to the registry. This error is extremely common in corporate environments where: - All outbound internet traffic must pass through a proxy server - The proxy requires Active Directory or LDAP authentication - Network security policies enforce web filtering and monitoring - VPNs route traffic through corporate network infrastructure The key challenge is that Docker daemon proxy settings are configured separately from your system's proxy settings, and credentials must be provided in a specific format that both systemd and Docker can understand.
Create a systemd drop-in file to set proxy environment variables for the Docker daemon:
# Create the directory for Docker service overrides
sudo mkdir -p /etc/systemd/system/docker.service.d
# Create the proxy configuration file
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf << 'EOF'
[Service]
Environment="HTTP_PROXY=http://username:[email protected]:8080"
Environment="HTTPS_PROXY=http://username:[email protected]:8080"
Environment="NO_PROXY=localhost,127.0.0.1,.example.com"
EOFReplace username, password, proxy.example.com, and 8080 with your actual proxy details.
Reload systemd and restart Docker:
sudo systemctl daemon-reload
sudo systemctl restart dockerVerify the configuration was applied:
sudo systemctl show --property=Environment dockerFor Docker Engine 23.0 and later, you can configure proxy settings directly in the daemon configuration file:
sudo tee /etc/docker/daemon.json << 'EOF'
{
"proxies": {
"http-proxy": "http://username:[email protected]:8080",
"https-proxy": "http://username:[email protected]:8080",
"no-proxy": "localhost,127.0.0.1,.example.com"
}
}
EOFRestart Docker to apply:
sudo systemctl restart dockerNote: If you're using both daemon.json and systemd environment variables, the daemon.json settings take precedence.
If your proxy password contains special characters, you must URL-encode them. Common character encodings:
| Character | URL Encoded |
|-----------|-------------|
| @ | %40 |
| # | %23 |
| $ | %24 |
| % | %25 |
| & | %26 |
| ! | %21 |
| ? | %3F |
| = | %3D |
| space | %20 |
Example: If your password is P@ss#word!, encode it as P%40ss%23word%21:
Environment="HTTPS_PROXY=http://username:P%40ss%23word%[email protected]:8080"For systemd with special characters, use an environment file instead:
# Create environment file (more reliable for special chars)
sudo tee /etc/default/docker-proxy << 'EOF'
HTTP_PROXY=http://username:P@ss#[email protected]:8080
HTTPS_PROXY=http://username:P@ss#[email protected]:8080
NO_PROXY=localhost,127.0.0.1
EOF
# Reference it in systemd override
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf << 'EOF'
[Service]
EnvironmentFile=/etc/default/docker-proxy
EOF
sudo systemctl daemon-reload
sudo systemctl restart dockerFor Docker Desktop, configure proxy settings through the GUI or config file:
Using Docker Desktop GUI:
1. Open Docker Desktop
2. Click the gear icon (Settings)
3. Navigate to Resources > Proxies
4. Enable Manual proxy configuration
5. Enter your proxy URLs with credentials:
- HTTP Proxy: http://username:[email protected]:8080
- HTTPS Proxy: http://username:[email protected]:8080
6. Click Apply & Restart
Using config.json (alternative method):
Edit ~/.docker/config.json (macOS/Linux) or %USERPROFILE%\.docker\config.json (Windows):
{
"proxies": {
"default": {
"httpProxy": "http://username:[email protected]:8080",
"httpsProxy": "http://username:[email protected]:8080",
"noProxy": "localhost,127.0.0.1"
}
}
}Note: The config.json approach configures proxy for containers, not the Docker daemon itself. For daemon proxy settings, use the GUI method.
Since Docker Engine 20.10.8 (which uses Go 1.16+), HTTPS URLs require the HTTPS_PROXY variable. Previously, HTTP_PROXY was used for all requests.
Always set both variables:
Environment="HTTP_PROXY=http://username:[email protected]:8080"
Environment="HTTPS_PROXY=http://username:[email protected]:8080"Note that even for HTTPS_PROXY, the proxy URL itself often uses http:// (not https://) because the proxy connection is established over HTTP, and then the HTTPS traffic is tunneled through it.
Test that both are set correctly:
sudo systemctl show --property=Environment docker | tr ' ' '\n' | grep -i proxyIf your corporate proxy uses NTLM or NTLMv2 authentication (common with Microsoft proxies), Docker cannot authenticate directly. Use Cntlm as a local proxy bridge:
# Install Cntlm
sudo apt-get install cntlm # Debian/Ubuntu
sudo yum install cntlm # RHEL/CentOS
# Generate password hash
cntlm -H -u username -d DOMAIN
# Configure Cntlm (/etc/cntlm.conf)
Username your_username
Domain YOUR_DOMAIN
Password your_password
# Or use PassNTLMv2 from the hash generated above
Proxy corporate-proxy.example.com:8080
NoProxy localhost, 127.0.0.*, 10.*, .example.com
Listen 127.0.0.1:3128Start Cntlm:
sudo systemctl enable cntlm
sudo systemctl start cntlmThen configure Docker to use the local Cntlm proxy (no authentication needed):
Environment="HTTP_PROXY=http://127.0.0.1:3128"
Environment="HTTPS_PROXY=http://127.0.0.1:3128"After configuring proxy settings, verify they are working:
# Check Docker daemon can reach the registry
docker info
# Test pulling a small image
docker pull hello-world
# Check Docker's network configuration
docker system info | grep -i proxyIf you still see errors, enable debug logging:
# Temporarily run Docker daemon with debug output
sudo dockerd --debug
# Or add to daemon.json
{
"debug": true
}Check the logs for proxy-related messages:
sudo journalctl -u docker.service -fSometimes Docker caches incorrect credentials. Clear them and try again:
# Logout from Docker Hub
docker logout
# Remove stored credentials
rm -rf ~/.docker/config.json
# For Docker Desktop, also try:
# Settings > Docker Engine > Reset to factory defaults (last resort)
# Restart Docker
sudo systemctl restart docker
# Try pulling again
docker pull hello-worldIf you have credential helpers configured, check their settings:
# Check what credential store is configured
cat ~/.docker/config.json | grep credsStore
# Test the credential helper
docker-credential-desktop listUnderstanding proxy configuration hierarchy:
Docker reads proxy settings from multiple locations with this precedence:
1. daemon.json proxies configuration (highest priority)
2. Systemd environment variables
3. CLI flags (--http-proxy, --https-proxy)
4. Shell environment variables (lowest priority, usually not read by daemon)
Proxy settings for containers vs. daemon:
There are two separate proxy configurations:
- Daemon proxy: Used by Docker daemon to pull images, push to registries, etc. (what this article covers)
- Container proxy: Used by containers during apt-get install, npm install, etc. (configured in ~/.docker/config.json or docker run -e HTTP_PROXY=...)
Debugging proxy issues:
# Test proxy connectivity from command line
curl -x http://username:[email protected]:8080 https://registry-1.docker.io/v2/
# Check DNS resolution
nslookup proxy.example.com
dig proxy.example.com
# Test proxy without Docker
https_proxy=http://username:[email protected]:8080 curl https://registry-1.docker.io/v2/SSL/TLS inspection proxies:
Some corporate proxies perform SSL inspection, which can cause certificate errors in addition to auth issues. You may need to:
1. Add the corporate CA certificate to Docker's trust store:
sudo cp corporate-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
sudo systemctl restart docker2. Or configure Docker to trust the registry through the proxy:
{
"insecure-registries": ["registry-1.docker.io"]
}(Not recommended for production)
Proxy PAC files:
Docker doesn't support PAC (Proxy Auto-Config) files directly. If your organization uses PAC files, you need to:
1. Determine the actual proxy server from the PAC file
2. Configure Docker with the direct proxy URL
Air-gapped environments:
If proxy configuration is too complex, consider setting up a private registry mirror:
# Run a local registry
docker run -d -p 5000:5000 --name registry registry:2
# Pull images on a connected machine, then push to local registry
docker pull nginx
docker tag nginx localhost:5000/nginx
docker push localhost:5000/nginximage operating system "linux" cannot be used on this platform
How to fix 'image operating system linux cannot be used on this platform' in Docker
manifest unknown: manifest unknown
How to fix 'manifest unknown' in Docker
cannot open '/etc/passwd': Permission denied
How to fix 'cannot open: Permission denied' in Docker
Error response from daemon: failed to create the ipvlan port
How to fix 'failed to create the ipvlan port' in Docker
toomanyrequests: Rate exceeded for anonymous users
How to fix 'Rate exceeded for anonymous users' in Docker Hub