Pular para o conteúdo
ecdsa.com
Go net/httpGo

Mensagem de erro

http: server gave HTTP response to HTTPS client

Cada programa acrescenta o próprio prefixo: o Docker imprime “Error response from daemon: Get \"https://<registry>/v2/\": http: server gave HTTP response to HTTPS client”, e programas em Go, “Get \"https://…\": http: server gave …”. Quando a resposta também não é HTTP, o Go diz “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)

O que significa

O cliente HTTP do Go iniciou um handshake TLS, e o servidor devolveu uma resposta HTTP não criptografada; o Go reconhece os bytes “HTTP/” e informa que o servidor fala HTTP, e não HTTPS. O caso mais conhecido é o docker pull ou o docker login em um registro auto-hospedado que roda sem TLS: o Docker exige HTTPS de todo registro que não esteja em um endereço de loopback nem tenha sido marcado explicitamente como inseguro.

Por que acontece

Como corrigir

  1. 1.

    Confirmar que a porta fala HTTP não criptografado

    Uma linha de status HTTP em resposta a http:// confirma isso. Use o endpoint TLS (ou http://, onde isso for aceitável).

    bash
    curl -si http://registry.example.com:5000/v2/ | head -1   # answers over plain HTTP?
  2. 2.

    Servir o registro via TLS

    Dê ao registro um certificado (de ACME público ou da CA da empresa) e configure-o, ou coloque na frente dele um proxy que faça a terminação do 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. 3.

    Último recurso: marcar o registro como inseguro (daemon.json)

    Listar o registro em insecure-registries no /etc/docker/daemon.json (e reiniciar o dockerd) permite que o Docker se comunique com ele em HTTP não criptografado. Imagens e credenciais passam então a trafegar sem criptografia e sem autenticação; use isso só em redes de laboratório isoladas.

    json
    {
      "insecure-registries": ["registry.example.com:5000"]
    }

Erros relacionados

Ver toda a base de erros de assinatura