This error occurs when Docker attempts to connect to a registry or server, but the SSL/TLS certificate presented does not match the hostname being accessed. The certificate's Common Name (CN) or Subject Alternative Names (SANs) do not include the domain you're trying to reach.
The "x509: certificate is valid for X, not Y" error is a TLS certificate validation failure that occurs when there's a mismatch between the hostname Docker is connecting to and the hostnames listed in the server's certificate. Every TLS certificate contains a list of valid hostnames in two fields: - **Common Name (CN):** The primary hostname the certificate was issued for - **Subject Alternative Names (SANs):** Additional hostnames the certificate covers (wildcards like `*.docker.io` are common) When Docker connects to a registry (e.g., `myregistry.com`), it checks whether that hostname appears in the certificate's CN or SAN list. If Docker finds `*.docker.io` in the certificate but is trying to connect to `myregistry.com`, verification fails because the certificate was issued for a completely different domain. This error typically indicates one of several situations: - **Network/proxy interception:** A corporate proxy or firewall is intercepting HTTPS traffic and presenting its own certificate - **DNS misconfiguration:** Your DNS is resolving the registry hostname to the wrong IP address - **Docker Machine IP changes:** After a reboot, docker-machine may get a new IP that doesn't match the certificate - **Wrong certificate installed:** The registry server has the wrong certificate configured
First, check what certificate the server is actually presenting to understand the mismatch:
# Check the certificate from the registry
openssl s_client -connect myregistry.com:443 -servername myregistry.com </dev/null 2>/dev/null | \
openssl x509 -noout -text | grep -A1 "Subject:"
# Check the Subject Alternative Names
openssl s_client -connect myregistry.com:443 -servername myregistry.com </dev/null 2>/dev/null | \
openssl x509 -noout -text | grep -A1 "Subject Alternative Name"
# Full certificate details
openssl s_client -showcerts -connect myregistry.com:443 </dev/null 2>&1 | head -50If the certificate shows unexpected hostnames (like your company's proxy hostname, *.dropbox.com, or a completely different domain), this indicates network interception or misconfiguration.
Corporate networks often intercept HTTPS traffic for security scanning. If you see unexpected certificate issuers, a proxy is likely involved:
# Check who issued the certificate
openssl s_client -connect registry-1.docker.io:443 </dev/null 2>/dev/null | \
openssl x509 -noout -issuer
# Expected: issuer=C = US, O = DigiCert Inc, ...
# If intercepted: issuer=CN = YourCompany Security Proxy, ...If proxy interception is detected:
1. Contact your IT department for the corporate root CA certificate
2. Install the corporate CA certificate:
# Ubuntu/Debian
sudo cp corporate-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
sudo systemctl restart docker
# RHEL/CentOS
sudo cp corporate-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
sudo systemctl restart docker3. Or configure Docker Desktop to use the corporate certificate via Settings
Ensure the registry hostname resolves to the correct IP address:
# Check DNS resolution
nslookup myregistry.com
dig myregistry.com
# Compare with expected IP from registry documentation
# or ping from a known-working machine
# Check /etc/hosts for any overrides
cat /etc/hosts | grep myregistry
# Test direct connection to the IP
curl -v https://<expected-ip>/ -H "Host: myregistry.com"If DNS is returning the wrong IP:
- Check your /etc/hosts file for incorrect entries
- Verify DNS server configuration in /etc/resolv.conf
- Try using a different DNS server temporarily:
# Test with Google DNS
nslookup myregistry.com 8.8.8.8If you're using Docker Machine and the IP address changed (common after rebooting), regenerate the certificates:
# List your Docker machines
docker-machine ls
# Check the current IP vs certificate IP
docker-machine ip default
docker-machine inspect default | grep -A5 "AuthOptions"
# Regenerate certificates for the machine
docker-machine regenerate-certs default
# Note: This will restart Docker and may stop running containers
# Confirm when prompted
# Verify the connection works
docker-machine env default
eval $(docker-machine env default)
docker infoFor Hyper-V users, you may need to set a static IP to prevent this recurring:
- Open Hyper-V Manager
- Configure your Docker VM's network adapter with a static IP
- Regenerate certificates after the IP change
If you control the registry, ensure the certificate includes all required hostnames:
# Generate a new certificate with proper SANs
openssl req -newkey rsa:4096 -nodes -sha256 \
-keyout registry.key -x509 -days 365 \
-out registry.crt \
-subj "/CN=myregistry.com" \
-addext "subjectAltName=DNS:myregistry.com,DNS:*.myregistry.com,IP:192.168.1.100"For Docker Registry v2:
Update your registry configuration to use the new certificate:
# config.yml
version: 0.1
storage:
filesystem:
rootdirectory: /var/lib/registry
http:
addr: :5000
tls:
certificate: /certs/registry.crt
key: /certs/registry.keyThen restart your registry:
docker restart registryAs a temporary workaround for development environments only, you can skip TLS verification:
# Edit Docker daemon configuration
sudo nano /etc/docker/daemon.jsonAdd the registry to the insecure list:
{
"insecure-registries": ["myregistry.com:5000"]
}Restart Docker:
sudo systemctl restart dockerWARNING: This completely disables TLS verification for this registry:
- Never use in production
- Vulnerable to man-in-the-middle attacks
- Only suitable for isolated development networks
- Better to fix the certificate properly
After applying any fix, verify the connection works:
# Test TLS connection
openssl s_client -connect myregistry.com:443 -servername myregistry.com </dev/null
# Verify certificate matches hostname
openssl s_client -connect myregistry.com:443 </dev/null 2>/dev/null | \
openssl x509 -noout -subject -issuer
# Test Docker login
docker login myregistry.com
# Test pulling an image
docker pull myregistry.com/test-image:latest
# Check Docker daemon logs if issues persist
sudo journalctl -u docker.service -fUnderstanding certificate hostname validation:
TLS certificates use two fields for hostname validation:
- CN (Common Name): Legacy field, limited to one hostname
- SAN (Subject Alternative Name): Modern standard, supports multiple hostnames and wildcards
Modern browsers and Docker prefer SAN over CN. A certificate with only CN may fail validation in some configurations.
Wildcard certificate limitations:
Wildcard certificates (*.example.com) only match one subdomain level:
- *.example.com matches registry.example.com
- *.example.com does NOT match dev.registry.example.com
- For multi-level subdomains, use explicit SANs
Docker Machine certificate storage:
Docker Machine stores certificates in:
~/.docker/machine/machines/<machine-name>/
├── ca.pem
├── cert.pem
├── key.pem
├── server.pem
└── server-key.pemSNI (Server Name Indication):
When multiple registries share an IP (common with CDNs), the client must send the hostname via SNI. Verify SNI is working:
openssl s_client -connect registry-1.docker.io:443 -servername registry-1.docker.ioDebugging in Kubernetes/containerd:
For containerd-based setups, check certificate configuration:
# View containerd registry config
cat /etc/containerd/config.toml | grep -A10 "registry.configs"
# Test with crictl
crictl pull myregistry.com/image:tagCommon interception scenarios:
1. Zscaler/corporate security: Contact IT for the Zscaler root CA
2. Charles Proxy/Fiddler: Disable SSL proxying for Docker traffic
3. Antivirus software: Some AV programs intercept HTTPS - check settings
image 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