← Blog Home

Como depurar “Enviado, mas não recebido” na visão do time de produto

br 2026-02-08 13:17:53

Como depurar “Enviado, mas não recebido” na visão do time de produto

Poucas frases dão tanta dor de cabeça quanto: “Aparece como enviado, mas eu não recebi”. Do lado do usuário, parece simples: ele clicou, o sistema confirmou, e nada chegou. Do lado do produto, isso pode ser qualquer coisa: atraso de fila, problema de autenticação, bounce silencioso, filtro do provedor, reputação de domínio/IP, webhooks perdidos, template quebrado, rate limit, ou até o destinatário olhando a caixa errada.

A boa notícia é que dá para investigar com método. Este guia é para times de produto: como estruturar triagem, que evidências pedir, quais métricas e logs devem existir, e como transformar um caso confuso em hipóteses testáveis e um plano de correção.

Por que esse problema é diferente (e por que produto precisa liderar)

“Não recebi” costuma ser uma falha de cadeia, não de um único componente. O time de produto entra porque a questão não é só técnica: é também experiência, confiança e conversão. Se um e-mail de verificação falha, o usuário não “espera”: ele abandona. Se um e-mail de reset não chega, o usuário acha que o sistema é inseguro. Se um e-mail transacional some, o suporte vira gargalo e o CAC “vaza” pelo ralo.

Produto precisa garantir três coisas: observabilidade (ver o que aconteceu), responsabilidade (quem age em cada etapa) e comunicação (o que o usuário vê quando dá errado).

Defina o que “enviado” significa no seu produto

Antes de depurar, alinhe o vocabulário. Em muitos produtos, “enviado” na UI significa apenas: “o backend aceitou o pedido e colocou na fila”. Em outros, significa “o provedor aceitou”. Em outros, significa “foi entregue na caixa do destinatário” (o que quase nunca é garantível).

Para evitar confusão interna e com o usuário, vale adotar estados claros: Solicitado (user action), Aceito (backend validou), Enfileirado, Enviado ao provedor, Aceito pelo provedor, Entregue (quando houver confirmação), Bounced, Bloqueado, Rejeitado, Spam/Quarentena (quando detectável).

Se o produto só exibe “enviado” quando está no estágio “aceito”, você está plantando a semente do ticket. Produto não precisa “prometer entrega”, mas precisa prometer a verdade.

Triagem rápida: perguntas que economizam horas

1) Qual e-mail, qual horário, qual fluxo?

Parece básico, mas é o que mais falta no primeiro contato. Peça: endereço do destinatário (com domínio), horário aproximado, fuso, tipo de e-mail (verificação, reset, convite, cobrança, recibo, marketing), e o contexto (primeiro envio ou reenvio). Em times de produto, isso vira um mini-formulário no suporte: sem isso, o time “caça” no escuro.

2) O usuário olhou spam, promoções e abas?

No Brasil, especialmente com Gmail e Outlook, o e-mail pode cair em Spam, Promoções ou até ficar escondido em filtros. Antes de chamar de incidente, crie um checklist simples para o suporte orientar: procurar pelo remetente, pelo assunto, por palavras-chave, e validar se há regras de filtro configuradas.

3) O domínio do destinatário tem histórico de bloqueio?

Alguns domínios corporativos têm políticas mais agressivas (filtros internos, quarentena). Se a maior parte dos casos vem de um domínio específico, isso sugere bloqueio por reputação ou política do receptor. É uma pista forte para priorizar autenticação e reputação.

4) O usuário está usando e-mail temporário?

Em produtos com onboarding rápido, parte dos usuários usa e-mail temporário. Esses endereços expiram, não suportam certos anexos, ou têm infraestrutura que pode atrasar recebimentos. Se esse for um cenário comum, o produto pode guiar: “use um e-mail permanente para recuperar conta”. Isso reduz tickets e melhora a taxa de sucesso em fluxos críticos.

Monte o “trace” do envio: um ID para governar todos

Se você pudesse escolher uma única melhoria estrutural para esse problema, seria: um ID de rastreio por mensagem visível e consistente em todo o pipeline. Esse ID precisa nascer no produto (no momento da ação do usuário) e atravessar: backend, fila, worker, provedor de e-mail, webhooks de evento, e armazenamento de eventos.

Do ponto de vista de produto, o ideal é ter: message_id (interno), provider_message_id (do provedor), e ligação com o usuário/conta e o fluxo (reset, verify etc). Assim, qualquer caso vira uma busca objetiva: “o que aconteceu com esta mensagem?”

Onde geralmente quebra: mapa do pipeline

Para depurar, pense em camadas. Em cada camada, há sintomas típicos e “provas” que você consegue coletar.

Camada A: Produto/UI e Backend (antes da fila)

  • Validação incorreta: e-mail mal formatado ou normalizado errado (ex.: espaços, maiúsculas, caracteres especiais).
  • Deduplicação agressiva: usuário clicou reenviar e o sistema bloqueou sem avisar (“já enviamos”).
  • Rate limit interno: API retorna sucesso, mas descarta silenciosamente.
  • Bug de template: renderização falha e o worker “engole” a mensagem.

Aqui, produto deve exigir que “sucesso” na UI só apareça quando houver uma evidência mínima: por exemplo, “solicitação registrada”, e um status consultável.

Camada B: Fila e workers

  • Atraso: backlog alto, picos, jobs lentos, concorrência baixa.
  • Falhas e retries: a mensagem falha e reentra em retry por minutos.
  • Poison messages: um payload específico quebra sempre (caracteres, encoding, template).
  • Configuração: worker não está consumindo uma fila, ou está consumindo o ambiente errado.

Sintoma clássico: usuário reclama “não recebi” e, horas depois, chega tudo junto. Esse é um cheiro de fila/worker.

Camada C: Provedor de e-mail (API SMTP/HTTP)

  • 429 / rate limit: provedor recusa por volume.
  • Rejeição por política: domínio sem autenticação adequada, remetente inconsistente, conteúdo suspeito.
  • Erros temporários: timeouts, DNS, problemas de rede.

Produto precisa garantir que a equipe tenha acesso ao status do provedor por message_id, e que eventos sejam armazenados com consistência.

Camada D: Entrega no destinatário (onde você tem menos controle)

  • Spam/quarentena: entregue “tecnicamente”, mas invisível ao usuário.
  • Bloqueio por reputação: IP ou domínio marcado.
  • Políticas corporativas: gateways internos seguram a mensagem.
  • Greylisting: atrasos intencionais para combater spam.

Essa camada é onde times se perdem. Não dá para “garantir inbox”. Dá para aumentar as chances com autenticação, reputação e conteúdo consistente.

Checklist de evidências: o que pedir (sem virar “ping-pong”)

Para o suporte coletar e produto acelerar a investigação, padronize o pacote mínimo:

  • E-mail do destinatário e domínio (ex.: gmail.com, outlook.com, empresa.com).
  • Horário aproximado do envio e do reenvio (se houve).
  • Fluxo (verificação, reset, convite, receipt etc).
  • Captura de tela do produto mostrando a ação (quando aplicável).
  • message_id interno (se existir) e status exibido.
  • Se chegou depois, quanto tempo demorou.
  • Se caiu no spam e se o usuário moveu para a caixa de entrada.

Isso transforma “não recebi” em um caso rastreável, e evita investigações “no feeling”.

Instrumentação que produto deve exigir

Se o time depende de logs manuais em servidores, você sempre vai estar atrasado. Produto deve tratar entrega de e-mail como um fluxo crítico e exigir telemetria de ponta a ponta.

Métricas (dashboards simples, mas obrigatórios)

  • Taxa de aceitação no backend (solicitações válidas vs inválidas).
  • Backlog da fila e tempo médio na fila (p95 e p99).
  • Taxa de envio ao provedor e latência (worker → provedor).
  • Taxa de bounce (hard vs soft) por domínio de destinatário.
  • Taxa de reclamação (quando disponível) e sinais de spam.
  • Taxa de entrega (delivered) e de eventos perdidos (webhook gap).

Logs estruturados (para busca por caso)

  • event=message_requested com user_id, fluxo, timestamp.
  • event=queued com queue_name e job_id.
  • event=provider_send_attempt com payload checksum e resultado.
  • event=provider_accepted com provider_message_id.
  • event=delivery_event (delivered/bounced/blocked/spam) via webhook.

O objetivo é que alguém do time consiga responder em minutos: foi enfileirado? foi aceito pelo provedor? houve bounce? houve atraso?

Autenticação e reputação: o lado “invisível” que derruba entregabilidade

Quando a taxa de “não recebi” cresce sem mudanças óbvias no produto, muitas vezes o problema é entregabilidade. Do ponto de vista de produto, o tema parece “infra”, mas o impacto é 100% produto: onboarding trava, reset falha, e churn sobe.

SPF, DKIM e DMARC (o trio que você precisa respeitar)

Sem entrar em implementação detalhada, pense assim: SPF diz quem pode enviar por você; DKIM prova que a mensagem não foi adulterada e que o remetente é legítimo; DMARC define a política quando SPF/DKIM não batem, e melhora a confiança. Se isso está mal configurado, provedores podem aceitar e “sumir” com o e-mail em filtros.

Reputação de domínio e IP

Se vocês enviam muita coisa (ou enviam conteúdo que parece “promo”), a reputação sofre. Mesmo e-mails transacionais podem ser afetados. Sintoma típico: Gmail entrega bem, mas domínios corporativos não; ou o contrário. Outro sintoma: de um dia para o outro, o volume “parece normal”, mas a entrega cai.

Conteúdo e template também pesam

Links encurtados, excesso de imagens, palavras “gatilho”, HTML malformado, ou inconsistência entre From e domínio real podem aumentar suspeita. Produto pode ajudar padronizando templates, reduzindo variações, e garantindo que e-mails críticos sejam “clean”: texto claro, poucos links, e um CTA principal.

Hipóteses comuns e como testar (do jeito que produto entende)

Hipótese 1: atraso de fila

Teste: olhe o tempo na fila (p95/p99). Compare horário do clique do usuário com horário do “provider_accepted”. Se a diferença é grande, o problema está entre backend e worker. Correção: aumentar concorrência, reduzir tempo do job, dimensionar filas, e colocar alertas de backlog.

Hipótese 2: provedor recusando silenciosamente

Teste: verifique respostas de API e logs de erro. Se há 4xx/5xx, categorize por tipo e domínio. Correção: retries com backoff, limites por domínio, e fallback para um segundo provedor em e-mails críticos.

Hipótese 3: bounce por domínio específico

Teste: agrupe bounces por domínio do destinatário e por tipo (hard/soft). Se um domínio dispara, pode ser reputação ou política do receptor. Correção: ajustar autenticação, aquecer envio, revisar conteúdo e, se necessário, contato com o receptor (em B2B).

Hipótese 4: usuário não encontra porque caiu em spam/promoções

Teste: peça ao usuário que procure pelo remetente e confirme se está no spam. Se muitos casos aparecem no spam, há um sinal de reputação/conteúdo. Correção: melhorar autenticidade, consistência de remetente, e templates mais “transacionais”. Além disso, produto pode ajustar microcopy: “verifique Spam/Promoções”.

Hipótese 5: bug de template/encoding

Teste: compare casos que falham com variáveis do template (nome com acento, caracteres especiais, emoji, idioma). Um erro de encoding pode quebrar o job e impedir o envio. Correção: validação de template, testes automatizados, e fallback para texto simples quando necessário.

O que o produto pode mudar hoje para reduzir reclamações

1) Pare de prometer “enviado” cedo demais

Se o usuário vê “enviado” no momento do clique, mas o e-mail ainda nem saiu do sistema, o produto está criando uma frustração inevitável. Mostre algo mais honesto: “Solicitação registrada” e um estado “em processamento”. Em fluxos críticos, vale oferecer um status com tentativa de reenvio e tempo estimado.

2) Adicione orientação contextual

Em verificação e reset, um texto curto ajuda muito: “Se não chegar em alguns minutos, verifique Spam/Promoções e tente reenviar.” É simples, mas reduz tickets, porque o usuário sente que o produto “prevê” a falha.

3) Botão de reenvio com limites e transparência

Reenvio infinito pode virar abuso e piorar reputação. Reenvio limitado com contagem regressiva funciona. Mas não bloqueie sem explicar. Se houver limite, diga: “Você pode reenviar em X segundos”. Transparência reduz irritação.

4) Alternativa de verificação

Dependendo do produto, oferecer um segundo canal (SMS, autenticação por app, ou link dentro do produto) pode salvar a conversão. Nem sempre é viável, mas para fluxos com alto impacto, vale considerar.

5) Suporte com “código do caso”

Se o usuário abre ticket, ele pode informar um código que mapeia para o message_id. Isso corta metade do tempo de triagem e melhora a percepção de profissionalismo.

Como conduzir um incidente sem virar caos

Quando o volume de reclamações sobe, produto precisa operar como “central de comando”: medir impacto, priorizar fluxos críticos e coordenar comunicação.

Passo 1: delimitar o impacto

  • É um fluxo específico (ex.: reset) ou todos?
  • É um domínio específico (ex.: hotmail/outlook) ou geral?
  • Começou depois de uma mudança (template, provedor, DNS, deploy)?
  • Há atraso (chega depois) ou não chega nunca?

Passo 2: ativar “war room” com dados

Sem dashboard e trace, vira gritaria. Com dashboard e trace, vira investigação. Um canal com engenharia, suporte e produto, olhando os mesmos números, resolve mais rápido.

Passo 3: comunicação para o usuário (sem prometer demais)

Se houver falha real, avise no produto e/ou status page: “Podem ocorrer atrasos no envio de e-mails”. E dê alternativa: reenviar, mudar e-mail, tentar outro canal, ou suporte. O objetivo é manter confiança enquanto a correção acontece.

Exemplo rápido (história curta, bem real)

Um SaaS brasileiro começou a receber tickets de “não recebi o e-mail de convite”. Produto achou que era template. Engenharia achou que era o provedor. O suporte só repetia “veja o spam”. Quando colocaram um trace por message_id, ficou claro: as mensagens estavam ficando 30 a 40 minutos na fila nos horários de pico. O sistema mostrava “enviado” no clique, mas o worker não dava conta.

Resolveram em duas frentes: aumentaram a concorrência do worker e mudaram a UI para “processando”. Resultado: queda grande nos tickets e aumento de conversão de convites aceitos, porque o usuário parou de desconfiar que “não funcionava”.

Checklist final para times de produto

  • Definição clara do que “enviado” significa na UI.
  • Estados do envio com rastreio por message_id.
  • Dashboards: backlog, latência, bounce, delivered, webhook gap.
  • Runbook com perguntas de triagem e pacote mínimo de evidências.
  • Autenticação bem cuidada (SPF/DKIM/DMARC) e consistência de remetente.
  • Templates estáveis e testados (inclusive com caracteres PT-BR).
  • UX de reenvio com transparência e limites.
  • Plano de incidente: medir impacto, coordenar times, comunicar sem exageros.

Conclusão

“Enviado, mas não recebido” não é um mistério insolúvel — é um problema de cadeia, e cadeia se resolve com rastreabilidade, métricas e linguagem correta na experiência do usuário. Do ponto de vista de produto, o objetivo é simples: reduzir atrito nos fluxos críticos e garantir que o usuário confie no que o sistema está dizendo. Quando você troca suposições por evidências, o problema deixa de ser “fantasma” e vira uma lista clara de ações.

Tip: Temporary inboxes are best for low-risk sign-ups and verification. Avoid sensitive accounts that require long-term recovery access.