How to fix x509: certificate is valid for *.docker.io, not myregistry.com in Docker
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.
Quick fix
Fixes x509
# 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 -50- Verify the certificate being presented
- Check for proxy/firewall interception
- Verify DNS resolution
- Regenerate Docker Machine certificates
# Check the certificate from the registryopenssl 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 Namesopenssl 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 detailsopenssl s_client -showcerts -connect myregistry.com:443 </dev/null 2>&1 | head -50x509: certificate is valid for *.docker.io, not myregistry.com
What this error means
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
Typical symptoms
- docker pull fails with 'x509: certificate is valid for X, not Y'
- docker login to private registry returns hostname mismatch error
- Error message shows certificate is valid for a different domain than expected
- The error occurs after changing network settings or rebooting
- Docker commands fail only on certain networks (e.g., corporate VPN)
- Error contains unexpected hostnames like *.dropbox.com or company internal names
- docker-machine commands fail with IP address mismatch errors
Common causes
- Corporate proxy/firewall intercepting HTTPS traffic and presenting its own certificate
- DNS resolving the registry hostname to the wrong server IP address
- Docker Machine IP address changed after reboot (common with Hyper-V/VirtualBox)
- Registry server misconfigured with certificate for wrong domain
- Certificate doesn't include all required Subject Alternative Names
- Network routing issue directing traffic to wrong server
- VPN or network configuration causing traffic to be routed incorrectly
How to fix "x509: certificate is valid for *.docker.io, not myregistry.com"
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 -fAdvanced notes
Understanding 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
Frequently asked questions
- What does "x509" mean?
- 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. com), it checks whether that hostname appears in the certificate's CN or SAN list. com, verification fails because the certificate was issued for a completely different domain.
- How do I fix "x509"?
- 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.
- What causes "x509"?
- Corporate proxy/firewall intercepting HTTPS traffic and presenting its own certificate DNS resolving the registry hostname to the wrong server IP address Docker Machine IP address changed after reboot (common with Hyper-V/VirtualBox)
- Is the "x509" error serious?
- It is a medium-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐Docker Official Documentation
- ๐
- ๐
- ๐ฌx509: certificate is valid for *.xyz.net, not docker.abc.xyz.net(Stack Overflow)
- ๐
- ๐ฌTLS failed to verify certificate: x509 - Docker Forums(Stack Overflow)
- ๐