Error message
Error response from daemon: Get "https://registry.example.com:5000/v2/": tls: failed to verify certificate: x509: certificate signed by unknown authority
The registry host and port are yours; docker push, pull and login all report it as "Error response from daemon: Get \"https://<registry>/v2/\": …". containerd, nerdctl, Podman and Kubernetes nodes pulling images print the same x509 text with their own prefixes.
Docker Engine (dockerd) — docker pull / push / login against a registry with an untrusted certificate
What it means
The Docker daemon (not the docker CLI) tried to reach the registry's API at /v2/ and could not verify its TLS certificate: the chain does not lead to a CA the daemon trusts. dockerd trusts the host's system CA bundle plus per-registry CAs placed in /etc/docker/certs.d/<registry>:<port>/. Private registries with company certificates and TLS-inspecting proxies are the usual causes.
Why it happens
A self-hosted registry with a private certificate
commonHarbor, GitLab registry, Nexus or registry:2 behind a certificate from a company or self-made CA.
A TLS-inspecting proxy in front of Docker Hub or other registries
commonThe daemon sees the proxy's certificates; without its root in the host store, every pull fails.
The CA was installed where the daemon does not look
occasionalCopying the CA into the client machine's store does nothing when the daemon runs elsewhere (Docker Desktop VM, remote DOCKER_HOST, CI runner). The certs.d directory name must match registry host and port exactly.
The registry omits its intermediate
occasionalGo (dockerd) does not fetch intermediates; a leaf-only registry fails even with a public CA.
How to fix it
- 1.
Install the CA for this registry in certs.d
/etc/docker/certs.d/<host>:<port>/ca.crt is read per request; in the reproduction, docker login succeeded right after adding it.
bash # Trust the registry's CA for this registry only (no daemon restart needed) sudo mkdir -p /etc/docker/certs.d/registry.example.com:5000 sudo cp corp-root-ca.pem /etc/docker/certs.d/registry.example.com:5000/ca.crt docker login registry.example.com:5000 - 2.
Install the CA system-wide and restart dockerd
For proxies and many registries, add the root to the host's bundle; the daemon reads it at start-up.
bash # Or system-wide (proxy roots, many registries), then restart the daemon sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt sudo update-ca-certificates sudo systemctl restart docker - 3.
Docker Desktop: trust the root on the host
Docker Desktop's VM takes trusted roots from the host operating system when it starts, so install the root there and restart Docker Desktop.
text Docker Desktop: the daemon runs in a VM. Add the root to the host's trust store (macOS Keychain "System" with "Always Trust", Windows "Trusted Root Certification Authorities") and restart Docker Desktop; it imports trusted host roots into the VM. - 4.
Check the registry's chain
If only the leaf is sent, configure the registry or its reverse proxy with the full chain.
bash openssl s_client -connect registry.example.com:5000 -servername registry.example.com -showcerts </dev/null 2>/dev/null \ | grep -E '^ *[0-9]+ s:|^ *i:'
Related errors
x509: certificate signed by unknown authorityGo crypto/x509tls: failed to verify certificate: x509: certificate signed by unknown authorityGo crypto/tls (Go ≥ 1.20)http: server gave HTTP response to HTTPS clientGo net/httpUnable to connect to the server: tls: failed to verify certificate: x509: certi…kubectl (client-go)