Mensaje de error
http: server gave HTTP response to HTTPS client
Los programas añaden su propio prefijo: Docker imprime «Error response from daemon: Get \"https://<registry>/v2/\": http: server gave HTTP response to HTTPS client», y los programas de Go, «Get \"https://…\": http: server gave …». Cuando la respuesta tampoco es HTTP, Go dice «tls: first record does not look like a TLS handshake».
Go net/http — the TLS handshake received a plain HTTP response (also printed by Docker, Helm, Terraform)
Qué significa
El cliente HTTP de Go inició un handshake TLS y el servidor contestó con una respuesta HTTP en texto plano; Go reconoce los bytes «HTTP/» e informa de que el servidor habla HTTP, no HTTPS. El caso más conocido es docker pull o docker login contra un registro autoalojado que funciona sin TLS: Docker exige HTTPS para todo registro que no esté en una dirección de loopback o marcado explícitamente como inseguro.
Por qué ocurre
Un registro de contenedores sin TLS
frecuenteregistry:2 (distribution), Harbor o Nexus arrancados con HTTP plano para hacer pruebas. Docker, containerd, Podman, Helm y Skopeo esperan HTTPS para todo lo que no sea localhost.
https:// con el puerto HTTP
frecuenteUna URL o una configuración que combina https:// con el puerto 80, el 8080 o el puerto de un servicio interno.
Un proxy termina TLS en otro puerto
ocasionalEl backend habla HTTP detrás de un balanceador de carga; los clientes que se saltan el balanceador y llegan al puerto del backend con https:// reciben este error.
Cómo solucionarlo
- 1.
Confirmar que el puerto habla HTTP plano
Una línea de estado HTTP en la respuesta a http:// lo confirma. Usa el endpoint TLS (o http:// donde sea aceptable).
bash curl -si http://registry.example.com:5000/v2/ | head -1 # answers over plain HTTP? - 2.
Servir el registro con TLS
Dale al registro un certificado (de ACME público o de la CA de la empresa) y configúralo, o pon delante un proxy que termine TLS.
yaml # Docker registry (distribution) config.yml: serve TLS http: addr: :5000 tls: certificate: /certs/registry.example.com.fullchain.pem key: /certs/registry.example.com.key - 3.
Último recurso: marcar el registro como inseguro (daemon.json)
Incluirlo en insecure-registries de /etc/docker/daemon.json (y reiniciar dockerd) permite que Docker se comunique con él por HTTP plano. Las imágenes y las credenciales viajan entonces sin cifrar y sin autenticar; úsalo solo en redes de laboratorio aisladas.
json { "insecure-registries": ["registry.example.com:5000"] }