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.
| Erro | O que aconteceu no nível da rede ou do protocolo | Onde 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_nameou 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
- 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.
- 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.
- Desligue a VPN e qualquer proxy. No Windows, abra Configurações > Rede e Internet > Proxy. No macOS, execute
scutil --proxypara ver as configurações de proxy. - 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.
- Reinicie as conexões do Chrome. Abra
chrome://net-internals/#socketse clique em “Close idle sockets” e “Flush socket pools”. Na aba “DNS” da mesma página, clique em “Clear host cache”. - 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 - Confira o arquivo hosts em busca de uma entrada antiga que envie o domínio para outro servidor:
C:\Windows\System32\drivers\etc\hostsno Windows,/etc/hostsno macOS e no Linux. - 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
- Reproduza de fora da sua rede com
curl -v https://example.com/eopenssl 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. - Veja qual endereço o DNS devolve e teste cada endereço com
--resolve. - Capture o FIN com o tcpdump para ver qual salto o envia.
- 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.
- 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. - 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
returne o código especial 444.