Mensagem de erro
Error response from daemon: Get "https://registry.example.com:5000/v2/": tls: failed to verify certificate: x509: certificate signed by unknown authority
O host e a porta mostrados serão os do seu registro; docker push, pull e login relatam o erro como “Error response from daemon: Get \"https://<registry>/v2/\": …”. O containerd, o nerdctl, o Podman e nós do Kubernetes que baixam imagens imprimem o mesmo texto x509 com os próprios prefixos.
Docker Engine (dockerd) — docker pull / push / login against a registry with an untrusted certificate
O que significa
O daemon do Docker (não a CLI docker) tentou acessar a API do registro em /v2/ e não conseguiu verificar o certificado TLS dele: a cadeia não leva a uma CA em que o daemon confie. O dockerd confia no bundle de CAs do sistema do host e também em CAs por registro colocadas em /etc/docker/certs.d/<registry>:<port>/. Registros privados com certificados da empresa e proxies com inspeção de TLS são as causas habituais.
Por que acontece
Um registro auto-hospedado com certificado privado
comumHarbor, registro do GitLab, Nexus ou registry:2 por trás de um certificado de uma CA da empresa ou criada por conta própria.
Um proxy com inspeção de TLS na frente do Docker Hub ou de outros registros
comumO daemon vê os certificados do proxy; sem a raiz dele no repositório do host, todo pull falha.
A CA foi instalada onde o daemon não procura
ocasionalCopiar a CA para o repositório da máquina cliente não adianta nada quando o daemon roda em outro lugar (VM do Docker Desktop, DOCKER_HOST remoto, runner de CI). O nome do diretório em certs.d precisa corresponder exatamente ao host e à porta do registro.
O registro não envia o intermediário
ocasionalO Go (dockerd) não busca intermediários; um registro que envia só o certificado folha falha mesmo com uma CA pública.
Como corrigir
- 1.
Instalar a CA deste registro em certs.d
O arquivo /etc/docker/certs.d/<host>:<port>/ca.crt é lido a cada requisição; na reprodução, o docker login funcionou logo depois que ele foi adicionado.
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.
Instalar a CA no sistema todo e reiniciar o dockerd
Para proxies e para muitos registros, adicione a raiz ao bundle do host; o daemon o lê na inicialização.
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: confiar na raiz no host
A VM do Docker Desktop obtém as raízes confiáveis do sistema operacional do host quando inicia, então instale a raiz lá e reinicie o 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.
Verificar a cadeia do registro
Se só o certificado folha é enviado, configure o registro ou o proxy reverso dele com a cadeia completa.
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:'
Erros relacionados
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)