Erros 502 específicos do usuário após o login — rastreados até DiscourseUpdates.has_unseen_features?

Olá,

Estou enfrentando um problema estranho com meu Discourse onde erros 502 ocorrem apenas para uma conta de usuário específica (admin) após o login, enquanto:

  • Usuários anônimos podem acessar o site normalmente

  • Outras contas de usuário podem fazer login e usar o site normalmente

  • O problema aparece apenas para uma conta específica (conta de administrador)


:puzzle_piece: Ambiente

  • Discourse instalado via configuração Docker oficial

  • Proxy reverso / CDN: ArvanCloud (semelhante ao Cloudflare)

  • O acesso à internet internacional está restringido / instável (GitHub e alguns serviços externos não estão acessíveis)

  • O Discourse não é atualizado há ~1 mês


:red_exclamation_mark: Sintomas

Ao acessar o site:

  • Se eu abrir o site em modo privado/anônimo → o site carrega normalmente

  • Se eu fizer login usando minha conta principal → imediatamente recebo 502 Bad Gateway

  • Se eu fizer login usando outra conta → tudo funciona bem

Portanto, o problema é claramente específico do usuário e acionado após a autenticação.


:page_facing_up: Logs de erro do CDN (ArvanCloud)

Dois erros principais aparecem:

1. Tempo limite do upstream ao ler o upstream

upstream timed out (110: Connection timed out) while reading upstream

URLs afetadas são principalmente assets, por exemplo:

  • /assets/browser-detect-*.js

  • /assets/plugins/automation-*.js

  • /assets/plugins/discourse-gamification-*.js

  • /assets/plugins/discourse-lazy-videos-*.js

2. Conexão encerrada prematuramente pelo upstream

upstream prematurely closed connection while reading response header from upstream

Por exemplo:

  • /stylesheets/common_theme_rtl_*.css

  • /theme-javascripts/*.js

Então, o CDN está esperando uma resposta do Discourse, mas o backend atinge o tempo limite ou fecha a conexão.


:magnifying_glass_tilted_left: O que encontrei no backend

Nos rastreamentos de pilha do Rails, o caminho do erro aponta para:

  • current_user_serializer.rb

  • discourse_updates.rb

  • método: DiscourseUpdates.has_unseen_features?

O que sugere que a falha/tempo limite ocorre ao verificar anúncios de novos recursos para usuários logados.

Como apenas um usuário é afetado, isso sugere fortemente que o problema é acionado durante a serialização específica do usuário, e não na renderização global do site.


Qualquer orientação seria apreciada.
Muito obrigado.

Você tentou em outros navegadores/dispositivos? Você tentou desativar as extensões do seu navegador?

Edição: Talvez eu tenha entendido mal. O site carrega no modo anônimo E logado como usuário?

Sim, testei em múltiplos dispositivos e navegadores, e não está relacionado a extensões de navegador.

O que estou vendo é específico do usuário, não específico do dispositivo:

  • Em qualquer dispositivo onde a conta de administrador já estava logada, abrir o site resulta imediatamente em 502 Bad Gateway.

  • Em modo anônimo/privado, o site carrega normalmente e consigo acessar a página de login.

  • A partir daí, consigo fazer login com sucesso com outra conta (não de administrador) e o site funciona bem.

  • Mas quando tento fazer login com a conta de administrador, logo após enviar o e-mail e a senha, consistentemente recebo 502, e a página nunca carrega.

Encontramos o mesmo problema e rastreamos a causa raiz.

A causa raiz é DiscourseUpdates.has_unseen_features? chamando GitUtils.has_commit?, que executa:

git merge-base --is-ancestor <sha> HEAD

Em imagens Docker do Discourse mais recentes, o repositório dentro do contêiner está configurado como um clone parcial com remoto promissor. Quando o SHA da funcionalidade não está presente localmente, o Git tenta uma busca sob demanda no remoto (upload-pack), o que leva ~3 a 4 segundos por chamada.

Como várias funcionalidades são verificadas, isso resulta em um tempo de requisição de mais de 30 segundos e, eventualmente, em um erro 502 (timeout do Unicorn), especialmente para usuários da equipe, onde essa verificação é executada.

Pontos-chave:

  • Ocorre apenas para usuários da equipe (via CurrentUserSerializer)

  • Causado por commits ausentes no clone parcial

  • Operações do Git em objetos ausentes acionam buscas remotas lentas

  • Reproduzível via git merge-base --is-ancestor <missing_sha> HEAD dentro do contêiner

Uma mitigação simples é armazenar em cache os resultados de GitUtils.has_commit? (por exemplo, por HEAD+SHA), o que evita chamadas repetidas e custosas ao Git.