Mensagem de erro
remote error: tls: bad certificate
Servidores Go registram “http: TLS handshake error from <client>: remote error: tls: bad certificate”. Clientes baseados em OpenSSL enviam alertas diferentes para a mesma rejeição (unknown_ca com TLS 1.2), então o texto no lado do servidor depende da biblioteca TLS do cliente.
Go crypto/tls — TLS alert 42 received from the peer; typically logged by a Go server whose certificate a Go client rejected
O que significa
O outro lado da conexão enviou o alerta TLS 42 (bad_certificate). No log de um servidor Go (“http: TLS handshake error from …: remote error: tls: bad certificate”), isso significa que um cliente recusou o certificado do servidor; clientes Go enviam esse alerta para qualquer falha de verificação (autoridade desconhecida, expiração, nome errado). Em um cliente Go, significa que o servidor rejeitou o certificado de cliente no TLS mútuo. O motivo real só aparece no lado que enviou o alerta.
Por que acontece
Um cliente Go não confia no certificado do servidor
comumCertificados autoassinados ou de CA privada, intermediários ausentes, certificados expirados ou um nome errado; o log do próprio cliente mostra “x509: …”.
TLS mútuo: o servidor rejeitou o certificado de cliente
comumAparece no lado do cliente quando o certificado dele está expirado, foi emitido por uma CA não confiável ou não tem o uso clientAuth.
Webhooks de admissão e operadores do Kubernetes
ocasionalO servidor de API (um cliente Go) rejeita o certificado de um webhook quando o caBundle não corresponde, e o servidor do webhook registra isso como bad certificate.
Como corrigir
- 1.
Encontrar o cliente que recusa o certificado e ler o erro dele
O endereço do cliente no log indica qual serviço examinar; o erro desse serviço informa a falha de verificação real.
bash # The log line names the client; its own error message says why it rejected the certificate journalctl -u myservice | grep 'remote error: tls: bad certificate' | grep -oE 'from [0-9a-f.:]+' | sort | uniq -c - 2.
Servir uma cadeia completa e confiável
Configure o servidor Go com um arquivo PEM de cadeia completa, emitido por uma CA em que todos os clientes confiam.
go // Serve the full chain: leaf first, then intermediates, in one PEM file log.Fatal(http.ListenAndServeTLS(":443", "fullchain.pem", "server.key", nil)) - 3.
Kubernetes: verificar o caBundle do webhook
O caBundle precisa conter a CA que emitiu o certificado de servidor do webhook; o CA injector do cert-manager mantém os dois sincronizados.
bash # Kubernetes webhooks: the API server verifies the webhook's certificate with caBundle kubectl get validatingwebhookconfiguration my-webhook -o jsonpath='{.webhooks[0].clientConfig.caBundle}' \ | base64 -d | openssl x509 -noout -subject -enddate