Ir para o conteúdo principal

Guias / Corrigir: guias para os erros que aparecem de verdade

ERR_CONNECTION_CLOSED: o que significa e como corrigir

ERR_CONNECTION_CLOSED significa que a outra ponta encerrou a conexão com um fechamento TCP normal antes de o Chrome receber uma resposta completa. O servidor, um balanceador de carga, um proxy, um firewall ou um software no seu próprio computador pode fazer isso, então a correção depende de onde a conexão foi fechada.

O que significa ERR_CONNECTION_CLOSED

O Chromium define CONNECTION_CLOSED (-100) como “A connection was closed (corresponding to a TCP FIN)” (uma conexão foi fechada, correspondendo a um FIN do TCP). Um FIN é a forma ordenada de encerrar uma conexão TCP: quem envia avisa que não tem mais dados. Um reset é a forma abrupta, e o Chrome a reporta como ERR_CONNECTION_RESET. No ERR_CONNECTION_CLOSED a conexão foi encerrada de forma educada, mas num momento em que o Chrome ainda esperava pelo handshake TLS ou pela resposta.

O Chrome não usa esse código para todo fechamento precoce. O código-fonte dele trata de duas maneiras uma conexão HTTP/1.x simples que fecha sem enviar nenhum byte. Se a conexão é nova, o Chrome reporta ERR_EMPTY_RESPONSE. Se a conexão foi reaproveitada de uma requisição anterior, o Chrome mantém ERR_CONNECTION_CLOSED, e um comentário no código dá o motivo: é “much more likely the server closed the socket before it received the request” (muito mais provável que o servidor tenha fechado o socket antes de receber a requisição). O Chrome então reenvia a requisição por outra conexão, de modo que o visitante raramente vê um erro só por causa desse caso.

Na prática, a página de erro aparece sobretudo em HTTPS. Se o outro lado fecha enquanto o handshake TLS está em andamento, o Chrome costuma reportar ERR_CONNECTION_CLOSED. O mesmo código é usado quando uma conexão HTTP/2 é fechada pelo outro lado, o que faz falhar todas as requisições que esperavam nessa conexão. A RFC 9113 diz que um endpoint DEVERIA enviar um frame GOAWAY antes de fechar uma conexão HTTP/2, para que o outro lado saiba quais requisições foram processadas. Um servidor ou balanceador de carga que fecha sem ele deixa o navegador com esse erro.

Como o erro aparece

O Chrome mostra “This site can't be reached” com o texto “example.com unexpectedly closed the connection” (o site fechou a conexão de forma inesperada) e o código ERR_CONNECTION_CLOSED. Ele sugere verificar a conexão, o proxy e o firewall, e executar o diagnóstico de rede do Windows. O Firefox costuma reportar um fechamento durante o handshake TLS como “Secure Connection Failed” (falha na conexão segura) com o código PR_END_OF_FILE_ERROR. A linha de comando mostra mais detalhes:

curl -sS http://example.com/
curl: (52) Empty reply from server

curl -sS https://example.com/
curl: (35) TLS connect error: error:0A000126:SSL routines::unexpected eof while reading

O primeiro caso é uma requisição HTTP simples numa conexão nova, em que o Chrome diz ERR_EMPTY_RESPONSE. O segundo é um fechamento durante o handshake TLS; o texto depende da biblioteca TLS, e este vem do OpenSSL 3. O openssl s_client mostra o mesmo evento como “unexpected eof while reading” com “SSL handshake has read 0 bytes”:

openssl s_client -connect example.com:443 -servername example.com </dev/null

Uma conexão reaproveitada que o servidor fechou aparece no curl -v quando duas URLs compartilham uma conexão. O curl percebe a conexão morta e tenta de novo, o que o Chrome também faz:

* Connection died, retrying a fresh connect (retry count: 1)

ERR_CONNECTION_CLOSED e erros parecidos

O Chrome mostra todos estes sob o mesmo título “This site can't be reached”, então o código embaixo é o que os diferencia. Os números são os códigos de erro internos do Chromium.

ErroO que aconteceu no nível da rede ou do protocoloOnde olhar primeiro
ERR_CONNECTION_TIMED_OUT (-118)O SYN saiu e nada voltou, nem SYN-ACK nem RST, até o cliente desistir.Firewalls que descartam pacotes, e se o host está no ar.
ERR_SSL_PROTOCOL_ERROR (-107)O outro lado respondeu, mas os dados não eram TLS válido, por exemplo HTTP puro numa porta TLS.O protocolo que a porta realmente fala e as configurações TLS do servidor.
ERR_CONNECTION_CLOSED (-100)O outro lado enviou um FIN. O Chrome não tinha uma resposta completa, muitas vezes durante o handshake TLS ou numa conexão HTTP/2.A borda na frente do site: blocos de servidor padrão, balanceador de carga, proxy, firewall, software de segurança.
ERR_CONNECTION_RESET (-101)A conexão estava aberta e depois um RST a encerrou durante o handshake ou a transferência.Os logs do proxy, do WAF e da aplicação naquele momento; antivírus, VPN ou filtragem na rede do cliente.
ERR_EMPTY_RESPONSE (-324)Uma conexão HTTP/1.x nova foi aberta, a requisição saiu e o servidor a fechou sem enviar nenhum dado.Workers que travaram e conexões fechadas de propósito (o return 444 do nginx).
ERR_CONNECTION_ABORTED (-103)A pilha de rede local desistiu porque os dados que enviou nunca foram confirmados.Perda de pacotes no link, uma conexão Wi-Fi instável ou um firewall que descarta tráfego no meio de uma transferência.

O que causa o ERR_CONNECTION_CLOSED

  • Um servidor coringa (catch-all) fecha a conexão. A requisição chegou a um bloco server que não conhece o nome do host, por exemplo depois de um erro de digitação em server_name ou quando o DNS ainda aponta para um servidor antigo, e esse bloco está configurado para fechar a conexão.
  • Um firewall, proxy ou filtro encerra a conexão. Equipamentos de segurança, redes de escolas e empresas, controles parentais e alguns filtros nacionais podem fechar uma conexão em vez de resetá-la, e a inspeção de TLS que falha num site também pode.
  • Uma conexão ociosa é fechada na hora errada. Um servidor ou balanceador de carga fecha uma conexão keep-alive ociosa enquanto o navegador envia uma requisição por ela. A RFC 9112 permite isso: um cliente, servidor ou proxy pode fechar uma conexão a qualquer momento.
  • Um processo do servidor para. Uma queda, uma morte por falta de memória, um worker reciclado ou uma reinicialização durante um deploy fecha os sockets do processo.
  • Uma conexão HTTP/2 termina sem GOAWAY. Limites de ociosidade e limites de requisições por conexão fecham conexões que carregam muitas requisições.
  • O endpoint TLS do servidor desiste. Uma biblioteca TLS que falha no ClientHello, ou um terminador TLS sobrecarregado ou reiniciando, pode encerrar o handshake com um fechamento simples.
  • Um software no computador do visitante interfere. A varredura HTTPS do antivírus, uma VPN, uma configuração de proxy ou uma entrada antiga no arquivo hosts que manda o domínio para o servidor errado.

Causas no servidor e configuração

Trabalhe da borda para dentro: primeiro o CDN ou balanceador de carga, depois o servidor web, depois a aplicação. Para cada salto, descubra se a conexão vinda do navegador termina ali.

Veja quem envia o FIN

No servidor, capture só os pacotes que carregam as flags FIN ou RST enquanto você reproduz o erro:

sudo tcpdump -ni any 'tcp port 443 and (tcp[tcpflags] & (tcp-fin|tcp-rst) != 0)'

Uma linha com Flags [F.] é um FIN, e Flags [R] ou [R.] é um reset. Se o primeiro FIN vem do endereço do servidor logo depois dos primeiros pacotes do cliente, o servidor ou a borda na frente dele fecha a conexão. Se nenhum pacote do cliente chega a esta máquina, a conexão é fechada antes de chegar aqui.

Blocos de servidor catch-all e endereços IP errados

Muitas configurações de nginx têm um servidor padrão que rejeita nomes de host desconhecidos. A documentação do nginx diz que o código não padrão 444 “closes a connection without sending a response header” (fecha a conexão sem enviar um cabeçalho de resposta):

server {
    listen 443 ssl default_server;
    ssl_certificate     /etc/ssl/default/fullchain.pem;
    ssl_certificate_key /etc/ssl/default/privkey.pem;
    return 444;   # fecha a conexão, não envia nada
}

Esse bloco está correto por si só. Ele vira problema quando o seu site de verdade não bate com nenhum outro bloco: um erro de digitação em server_name, um nome www que falta ou um domínio que o DNS aponta para a máquina errada. Os visitantes então recebem uma conexão fechada, que pode aparecer como ERR_CONNECTION_CLOSED ou como ERR_EMPTY_RESPONSE. Liste os nomes para os quais o servidor responde e teste um servidor diretamente, mesmo que o DNS diga outra coisa:

sudo nginx -T | grep -n server_name
dig +short example.com
curl -vk --resolve example.com:443:203.0.113.10 https://example.com/

A opção --resolve faz o curl se conectar ao endereço que você informa e, ainda assim, enviar o nome de host correto. Se um endereço funciona e outro fecha, o segundo leva a um servidor que não atende o site. O guia quem hospeda um site mostra como descobrir qual provedor é dono de um endereço.

Keep-alive e timeouts de ociosidade

Um proxy na frente deve desistir de uma conexão ociosa com o backend antes que o backend o faça. Se o backend fecha primeiro, o proxy pode enviar a próxima requisição por uma conexão que já está fechada. O mesmo vale entre um balanceador de carga e seus destinos. A AWS documenta um timeout de ociosidade padrão de 60 segundos no Application Load Balancer e recomenda que o timeout de ociosidade da aplicação seja maior; caso contrário, o visitante pode receber um 502 Bad Gateway. O Node.js fecha conexões ociosas após 5 segundos por padrão, muito abaixo desse valor:

const http = require('node:http');
const server = http.createServer(app);
server.keepAliveTimeout = 65 * 1000;   // maior que o timeout de ociosidade de 60 s do balanceador de carga
server.listen(3000);

O nginx mantém conexões ociosas de clientes por 75 segundos por padrão (keepalive_timeout 75s;). Quando um backend fecha a conexão antes de enviar uma resposta, o nginx registra upstream prematurely closed connection while reading response header from upstream. O guia de ERR_CONNECTION_RESET cobre o lado do proxy desse problema com mais detalhes.

Quedas e reinicializações

sudo journalctl -k --since "1 hour ago" | grep -i -E "out of memory|killed process"
sudo journalctl -u myapp --since "1 hour ago" --no-pager

Compare a morte ou reinicialização de um worker com os horários das requisições que falharam. Uma queda pode produzir qualquer um dos dois erros: o cliente vê um FIN ou um RST dependendo de o processo ainda ter dados não lidos quando os sockets foram fechados.

Como aparece visto de fora

  • Fechada de todos os locais, durante o handshake: o servidor ou a borda fecha conexões TLS desconhecidas ou quebradas. Confira o servidor padrão, o certificado do nome solicitado e os registros DNS.
  • Fechada só de alguns locais: um dos vários endereços IP devolvidos pelo DNS não hospeda o site, um nó do CDN naquela região está com problema, ou um filtro naquela rede fecha a conexão.
  • O HTTP puro funciona, o HTTPS fecha: o problema está na camada TLS, como o certificado, o tratamento do nome do servidor ou um terminador na frente do servidor. O guia SSL handshake failed cobre o próprio handshake.
  • Fechada de vez em quando, de forma aleatória: timeouts de ociosidade, workers reciclados ou um servidor com problema atrás de um balanceador de carga.
  • Normal em todos os pontos de verificação, fechada só para você: a causa está na sua rede ou no seu dispositivo, como antivírus, VPN, proxy, o arquivo hosts ou o seu provedor.

O verificador HTTP confere o status HTTP, o tempo de resposta e a disponibilidade do servidor de um host a partir de locais do mundo todo, para você distinguir um fechamento que afeta o site inteiro de um ligado a uma única rede.

Como corrigir o ERR_CONNECTION_CLOSED

Se você é o visitante

  1. Recarregue a página uma ou duas vezes. Uma conexão que o servidor tinha acabado de fechar é substituída por uma nova na tentativa seguinte.
  2. Tente outra rede, como dados móveis em vez de Wi-Fi. Se o site carregar, a causa está na sua rede ou no seu dispositivo.
  3. Desligue a VPN e qualquer proxy. No Windows, abra Configurações > Rede e Internet > Proxy. No macOS, execute scutil --proxy para ver as configurações de proxy.
  4. Pause a varredura HTTPS do antivírus (muitas vezes chamada de proteção da web ou varredura SSL/TLS) e tente de novo. Se ajudar, adicione uma exceção para o site em vez de deixar a varredura desligada.
  5. Reinicie as conexões do Chrome. Abra chrome://net-internals/#sockets e clique em “Close idle sockets” e “Flush socket pools”. Na aba “DNS” da mesma página, clique em “Clear host cache”.
  6. No Windows, atualize a pilha de rede. Execute estes comandos num Prompt de Comando como administrador e depois reinicie:
    ipconfig /flushdns
    netsh winsock reset
    netsh int ip reset
  7. Confira o arquivo hosts em busca de uma entrada antiga que envie o domínio para outro servidor: C:\Windows\System32\drivers\etc\hosts no Windows, /etc/hosts no macOS e no Linux.
  8. Desative as extensões ou use uma janela anônima. Se o erro desaparecer, reative as extensões uma de cada vez.

Se você administra o site

  1. Reproduza de fora da sua rede com curl -v https://example.com/ e openssl s_client. Um fechamento durante o handshake aponta para o endpoint TLS; um fechamento depois da requisição aponta para o servidor web ou a aplicação.
  2. Veja qual endereço o DNS devolve e teste cada endereço com --resolve.
  3. Capture o FIN com o tcpdump para ver qual salto o envia.
  4. Leia os logs de cada salto: balanceador de carga ou CDN, log de erros do servidor web, log da aplicação e regras de WAF ou IPS que fecham conexões em vez de devolver uma página de erro. Procure erros de upstream, quedas e reinicializações no horário da falha.
  5. Confira os blocos server, os certificados e os servidores padrão dos nomes que você atende. Recarregue com segurança com sudo nginx -t && sudo systemctl reload nginx.
  6. Alinhe os timeouts de ociosidade: o timeout de keep-alive do backend deve ser maior que o timeout do proxy ou balanceador de carga na frente dele.

Detectando conexões fechadas cedo

Conexões fechadas costumam afetar uma região ou um de vários servidores, e uma verificação rápida a partir da sua própria rede pode deixar passar as duas coisas. A HostTracker monitora sites desde 2004 e os verifica a partir de mais de 300 pontos de verificação em 158 cidades. Ela envia alertas por e-mail, SMS, chamada de voz, Slack, Telegram e mais, de modo que um padrão como “fechada só em duas regiões” aparece nos resultados em vez de nas reclamações dos visitantes.

Perguntas frequentes

Qual a diferença entre ERR_CONNECTION_CLOSED e ERR_CONNECTION_RESET?

Closed significa que o outro lado enviou um FIN, o fim ordenado de uma conexão TCP. Reset significa que enviou um RST, que encerra a conexão na hora e descarta os dados em trânsito. O guia de reset cobre o segundo caso.

O ERR_CONNECTION_CLOSED é culpa minha ou do site?

Não dá para saber pela mensagem. Carregue o site a partir de outra rede ou execute uma verificação de vários locais. Se carregar lá, o problema está no seu dispositivo ou na sua rede. Se falhar em todo lugar, o site ou a borda dele fecha as conexões.

Por que acontece só em sites HTTPS?

O handshake TLS é um lugar comum para o Chrome encontrar uma conexão fechada, porque é o primeiro passo em que um firewall, um servidor padrão ou um terminador TLS pode decidir encerrar a troca. O HTTP puro numa conexão nova é reportado como ERR_EMPTY_RESPONSE.

Por que recarregar às vezes resolve?

Quando um servidor fecha uma conexão keep-alive ociosa justo quando o Chrome a reutiliza, a tentativa seguinte usa uma conexão nova. O Chrome repete muitas dessas requisições por conta própria, então a página de erro só aparece quando a nova tentativa também falha.

Uma VPN ou um antivírus pode causar ERR_CONNECTION_CLOSED?

Sim. Os dois ficam entre o navegador e o site. Um gateway de VPN ou um proxy corporativo pode fechar conexões que está configurado para recusar, e a varredura HTTPS do antivírus pode encerrar uma conexão quando não consegue inspecioná-la.

Limpar o cache do navegador ajuda?

Em geral não, porque o cache HTTP não está envolvido. O que conta são os pools de conexões e o cache de DNS. Use os botões “Flush socket pools” e “Clear host cache” em chrome://net-internals.

Por que recebo ERR_CONNECTION_CLOSED no localhost?

O servidor de desenvolvimento provavelmente caiu ou reiniciou enquanto tratava a requisição. Leia o terminal em que ele roda em busca de uma exceção ou de uma mensagem de saída.

Fontes e leitura adicional

  • Chromium net error list: as definições de CONNECTION_CLOSED (-100) e dos outros códigos da tabela acima.
  • RFC 9112, HTTP/1.1: a seção 9.5 sobre falhas e timeouts, e a seção 9.6 sobre o fechamento de uma conexão.
  • RFC 9113, HTTP/2: a seção 6.8 sobre o frame GOAWAY, e a seção 9.1 sobre o gerenciamento de conexões.
  • nginx rewrite module: a diretiva return e o código especial 444.

Verificar agora

Faça a verificação gratuita no seu próprio site, sem precisar de conta.

HTTP check

Monitorar permanentemente

Seja avisado no momento em que algo quebrar: o HostTracker verifica de mais de 300 localidades e notifica você por e-mail, SMS, Slack, Telegram e mais.

Recursos do HostTracker

Mais nesta seção: Corrigir: guias para os erros que aparecem de verdade