How to fix x509: certificate signed by unknown authority in Docker
This error occurs when Docker cannot verify the SSL/TLS certificate of a registry or server. It typically happens with private registries using self-signed certificates, corporate proxies that intercept HTTPS traffic, or when the CA certificate is not installed on the Docker host.
Quick fix
Fixes x509
# Create the directory for your registry (include port if not 443)
sudo mkdir -p /etc/docker/certs.d/your-registry.example.com:5000
# Copy your CA certificate (must be named ca.crt)
sudo cp your-ca-certificate.crt /etc/docker/certs.d/your-registry.example.com:5000/ca.crt
# Restart Docker to apply changes
sudo systemctl restart docker- Add certificate to Docker's certs.d directory
- Add certificate to the system CA store
- Extract the certificate from the registry
- Configure insecure registry (development only)
# Create the directory for your registry (include port if not 443)sudo mkdir -p /etc/docker/certs.d/your-registry.example.com:5000# Copy your CA certificate (must be named ca.crt)sudo cp your-ca-certificate.crt /etc/docker/certs.d/your-registry.example.com:5000/ca.crt# Restart Docker to apply changessudo systemctl restart dockerx509: certificate signed by unknown authority
What this error means
The "x509: certificate signed by unknown authority" error appears when Docker's TLS verification fails because it cannot find a trusted Certificate Authority (CA) that signed the certificate presented by the registry or server. Docker relies on secure HTTPS connections to verify the authenticity and integrity of container images. This commonly happens in several scenarios: - **Private registries** using self-signed certificates that aren't in Docker's trust store - **Corporate environments** where proxy servers intercept HTTPS traffic and re-sign certificates with their own CA - **Air-gapped environments** where internal CAs are used for security compliance - **Misconfigured certificate chains** where intermediate certificates are missing The x509 package in Go (which Docker uses) validates certificates against the system's CA certificate store and Docker's own certificate directory. When neither contains the signing CA, Docker refuses the connection to prevent potential man-in-the-middle attacks.
Typical symptoms
- docker pull fails with 'x509: certificate signed by unknown authority'
- docker login to private registry returns certificate error
- docker push fails when connecting to private/corporate registry
- The same commands work from another machine but not from yours
- Error occurs only when behind corporate firewall or VPN
- Docker build fails when pulling base images from private registry
- Error appears after changing network settings or proxy configuration
Common causes
- Private registry uses a self-signed certificate not trusted by the Docker host
- Corporate proxy/firewall intercepts HTTPS traffic and re-signs certificates
- CA certificate is not installed in the system's certificate store
- CA certificate is installed in system store but Docker wasn't restarted
- Certificate chain is incomplete (missing intermediate certificates)
- Docker's certs.d directory doesn't contain the registry certificate
- Certificate has expired or is not yet valid
How to fix "x509: certificate signed by unknown authority"
The most direct fix is to place the CA certificate in Docker's certificate directory. This tells Docker to trust certificates signed by that CA for the specific registry:
# Create the directory for your registry (include port if not 443)
sudo mkdir -p /etc/docker/certs.d/your-registry.example.com:5000
# Copy your CA certificate (must be named ca.crt)
sudo cp your-ca-certificate.crt /etc/docker/certs.d/your-registry.example.com:5000/ca.crt
# Restart Docker to apply changes
sudo systemctl restart dockerThe directory name must match exactly how you reference the registry in your Docker commands:
- Registry at myregistry.com on port 443: /etc/docker/certs.d/myregistry.com/ca.crt
- Registry at myregistry.com:5000: /etc/docker/certs.d/myregistry.com:5000/ca.crt
Adding the certificate to your operating system's CA store makes it trusted system-wide, including by Docker:
Ubuntu/Debian:
# Copy certificate to system CA directory
sudo cp your-ca-certificate.crt /usr/local/share/ca-certificates/
# Update CA certificates
sudo update-ca-certificates
# Restart Docker
sudo systemctl restart dockerRHEL/CentOS/Fedora:
# Copy certificate to CA trust directory
sudo cp your-ca-certificate.crt /etc/pki/ca-trust/source/anchors/
# Update CA trust
sudo update-ca-trust
# Restart Docker
sudo systemctl restart dockerOpenSUSE:
# Copy certificate
sudo cp your-ca-certificate.crt /etc/pki/trust/anchors/
# Update certificates
sudo update-ca-certificates
# Restart Docker
sudo systemctl restart dockerIf you don't have the CA certificate file, you can extract it directly from the registry:
# Extract certificate from the registry
openssl s_client -showcerts -connect your-registry.example.com:443 </dev/null 2>/dev/null | \
openssl x509 -outform PEM > registry-cert.crt
# View certificate details to verify
openssl x509 -in registry-cert.crt -text -noout | head -20
# For registries with multiple certificates in the chain,
# save all of them (intermediate + root)
openssl s_client -showcerts -connect your-registry.example.com:443 </dev/null 2>/dev/null | \
awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ print }' > full-chain.crtAfter extracting, place the certificate in Docker's certs.d directory or the system CA store as shown in previous steps.
For development or testing environments where certificate management isn't critical, you can configure Docker to skip TLS verification for specific registries:
# Edit or create Docker daemon configuration
sudo nano /etc/docker/daemon.jsonAdd your registry to the insecure-registries list:
{
"insecure-registries": ["your-registry.example.com:5000"]
}Then restart Docker:
sudo systemctl restart dockerWarning: This disables TLS verification entirely for the specified registry. Never use this in production as it makes you vulnerable to man-in-the-middle attacks. Only use for:
- Local development registries
- Temporary testing scenarios
- Isolated networks with no external access
In corporate environments, security appliances often intercept HTTPS traffic and re-sign certificates. You need to install the corporate root CA certificate:
1. Obtain your corporate CA certificate - Contact your IT department or security team
2. For Docker on Linux:
# Add corporate CA to system store
sudo cp corporate-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
sudo systemctl restart docker3. For Docker Desktop on Windows:
- Export the corporate CA from Windows Certificate Manager
- Open Docker Desktop Settings > Docker Engine
- Or place certificate in %USERPROFILE%\.docker\certs.d\<registry>
4. For Docker Desktop on macOS:
- Add certificate to Keychain Access
- Mark it as "Always Trust"
- Restart Docker Desktop
5. Verify proxy is the issue:
# Check if proxy is intercepting certificates
curl -v https://registry-1.docker.io 2>&1 | grep -i "issuer"
# If issuer is your company name instead of DigiCert/Amazon/etc., proxy is interceptingDocker caches certificate information, so you must restart the Docker daemon after any certificate changes:
# Linux with systemd
sudo systemctl restart docker
# Linux with SysVinit
sudo service docker restart
# Verify Docker is running
docker info
# Test registry connection
docker pull your-registry.example.com:5000/test-imageDocker Desktop (Windows/macOS):
1. Right-click Docker icon in system tray
2. Select "Restart"
3. Or quit and reopen Docker Desktop
If the error persists after restart, verify the certificate is in the correct location:
# Check Docker's certificate directory
ls -la /etc/docker/certs.d/
# Check system CA certificates were updated
ls -la /etc/ssl/certs/ | grep your-cert-nameAdvanced notes
Certificate locations Go/Docker checks:
Docker (via Go) checks certificates in these locations:
- /etc/docker/certs.d/<registry>/ca.crt - Registry-specific
- /etc/ssl/certs/ca-certificates.crt (Debian/Ubuntu)
- /etc/pki/tls/certs/ca-bundle.crt (RHEL/CentOS)
- /etc/ssl/ca-bundle.pem (OpenSUSE)
Using client certificates:
If your registry requires client certificate authentication, place all three files in the certs.d directory:
/etc/docker/certs.d/your-registry.example.com/
├── ca.crt # CA certificate
├── client.cert # Client certificate
└── client.key # Client private keyKubernetes/containerd:
For Kubernetes clusters using containerd (v1.19+), configure certificates in containerd's config:
# /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.configs."your-registry.example.com".tls]
ca_file = "/etc/containerd/certs.d/your-registry.example.com/ca.crt"Self-signed certificate generation:
For development registries, generate a proper self-signed certificate:
# Generate CA and registry certificate
openssl req -newkey rsa:4096 -nodes -sha256 \
-keyout registry.key -x509 -days 365 \
-out registry.crt -subj "/CN=your-registry.example.com" \
-addext "subjectAltName=DNS:your-registry.example.com,IP:192.168.1.100"Debugging certificate chains:
# View full certificate chain
openssl s_client -showcerts -connect registry.example.com:443 </dev/null
# Verify certificate against specific CA
openssl verify -CAfile ca.crt registry.crtFrequently asked questions
- What does "x509" mean?
- The "x509: certificate signed by unknown authority" error appears when Docker's TLS verification fails because it cannot find a trusted Certificate Authority (CA) that signed the certificate presented by the registry or server. Docker relies on secure HTTPS connections to verify the authenticity and integrity of container images. This commonly happens in several scenarios: - Private registries using self-signed certificates that aren't in Docker's trust store - Corporate environments where proxy servers intercept HTTPS traffic and re-sign certificates with their own CA - Air-gapped environments where internal CAs are used for security compliance - Misconfigured certificate chains where intermediate certificates are missing The x509 package in Go (which Docker uses) validates certificates against the system's CA certificate store and Docker's own certificate directory.
- How do I fix "x509"?
- This error occurs when Docker cannot verify the SSL/TLS certificate of a registry or server. It typically happens with private registries using self-signed certificates, corporate proxies that intercept HTTPS traffic, or when the CA certificate is not installed on the Docker host.
- What causes "x509"?
- Private registry uses a self-signed certificate not trusted by the Docker host Corporate proxy/firewall intercepts HTTPS traffic and re-signs certificates CA certificate is not installed in the system's certificate store
- 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
- 💬docker pull certificate signed by unknown authority(Stack Overflow)
- 💬Docker Private Registry x509 certificate error - Docker Forums(Stack Overflow)
- 📖Verify repository client with certificates - Docker Docs(Official Docs)
- 📝
- 📝
- 💬docker pull fails with x509 certificate error - Red Hat(Stack Overflow)