Nodemailer no Windows 11: como corrigir “SMTP service is missing” e o erro ECONNREFUSED ::1:587

Está enfrentando o erro “SMTP service is missing on Windows 11” ao usar o Nodemailer e vendo mensagens como ECONNREFUSED ::1:587? Este guia explica por que isso acontece no Windows 11, como corrigir de forma definitiva e como diagnosticar falhas de conexão, TLS e firewall com exemplos práticos.

Índice

Visão geral do problema

Ao enviar e‑mails com Nodemailer em um servidor Node.js local, aparecem erros de conexão como ECONNREFUSED ::1:587. Testes com portas locais tradicionais de SMTP falham e nenhum serviço “Simple Mail Transfer Protocol” é exibido no services.msc. O log pode mostrar algo como “Resolved localhost as ::1” (loopback IPv6). Curiosamente, ao usar um provedor externo (por exemplo, Mailtrap), tudo funciona.

Mensagem‑chave: não é um bug do Nodemailer. É um problema de configuração de host/porta e de expectativa sobre um “SMTP local” no Windows 11.

Causa raiz

  • Windows 11 não oferece um serviço SMTP nativo no cliente que você possa iniciar via services.msc. Logo, não há nada escutando em localhost:25, localhost:587 etc., a menos que você instale deliberadamente um servidor SMTP de terceiros.
  • O Nodemailer não precisa de um SMTP local. Ele se conecta a um servidor SMTP remoto (Mailtrap, Outlook, Gmail, SendGrid e afins). Se o seu código tentar usar localhost, receberá ECONNREFUSED porque não há servidor local ativo.
  • ::1 é o loopback IPv6. Quando o log mostra “Resolved localhost as ::1”, significa que “localhost” foi resolvido para o endereço de retorno IPv6, e não para o IPv4 127.0.0.1. Isso, por si só, não é um erro; apenas indica que a tentativa foi local.

Solução recomendada

Ajuste o transporte do Nodemailer para apontar explicitamente para o host do provedor SMTP remoto e use as credenciais corretas. Não use localhost a menos que você tenha instalado um SMTP de testes.

const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: 'sandbox.smtp.mailtrap.io', // <-- use o host do provedor
  port: 2525,                       // ou 587/465 conforme o provedor
  secure: false,                    // true somente para 465 (TLS implícito)
  auth: {
    user: 'SEU_USER',
    pass: 'SUA_SENHA'
  },
  // úteis para diagnóstico
  logger: true,  // registra eventos
  debug: true    // mostra conversa SMTP
});

// Teste de conectividade e autenticação
(async () => {
  await transporter.verify(); // "Server is ready to take our messages"
  await transporter.sendMail({
    from: 'no-reply@exemplo.com',
    to: 'destino@exemplo.com',
    subject: 'Teste',
    text: 'Olá!'
  });
})();

Dica: se os logs continuarem mostrando “localhost” ou “::1”, algum trecho do código está criando ou retornando um transporter diferente do esperado, ou sobrescrevendo as opções. Revise importações, fábricas de transporte, inversão de controle e variáveis de ambiente.

Verificação de conectividade

Não use ping para testar portas SMTP — ping usa ICMP e não TCP. Prefira o PowerShell:

# Teste de porta TCP
Test-NetConnection sandbox.smtp.mailtrap.io -Port 2525

Resultado esperado (parte relevante):
TcpTestSucceeded : True

Se o teste falhar, investigue DNS, firewall ou políticas de rede (VPN/proxy corporativo).

Procedimento de diagnóstico

Conferir o transporte do Nodemailer

Confirme o host efetivo utilizado no envio. Antes de sendMail, insira:

console.log('Transport options:', transporter.options);

Verifique se host corresponde ao do provedor (ex.: sandbox.smtp.mailtrap.io) e não a localhost.

Logs e mensagens comuns

Mensagem de erroIndicaçãoComo agir
ECONNREFUSED ::1:587Tentativa local em porta sem serviço ativoTrocar o host para o do provedor SMTP remoto
ETIMEDOUTBloqueio de saída, latência ou indisponibilidadeChecar firewall, proxy, VPN e Test-NetConnection
ENOTFOUND / EAI_AGAINProblema de DNSVerificar Resolve-DnsName e configuração de DNS
Falha de autenticaçãoCredenciais incorretasRevalidar usuário/senha, OAuth2 ou senhas de app

Checagem de portas e firewall

Confirme se há algo escutando localmente (apenas se estiver usando um SMTP local de testes):

Get-NetTCPConnection -State Listen |
  Where-Object { $_.LocalPort -in 25,465,587,2525 } |
  Select-Object LocalAddress, LocalPort, OwningProcess

Se você não instalou um servidor SMTP local, é esperado que não haja nada nas portas acima. Para o envio real, o tráfego deve sair para a Internet nas portas do provedor. Verifique regras de saída do “Firewall do Windows com Segurança Avançada” e antivírus que possam bloquear SMTP.

Configuração de TLS

No Nodemailer, secure controla TLS implícito na conexão inicial. Para STARTTLS, use secure: false e a negociação ocorrerá após o comando EHLO se o servidor suportar.

Porta típicasecureModoObservações
587falseSTARTTLSPadrão moderno para submissão autenticada
465trueTLS implícitoConexão já nasce criptografada
2525false na maioriaVariável por provedorPorta alternativa para provedores de sandbox e produção

Uso de SMTP local para desenvolvimento

Se você deseja apenas capturar e visualizar e‑mails em ambiente de desenvolvimento, instale um capturador local (também chamado de “fake SMTP”), como smtp4dev, Papercut SMTP ou MailHog. Essas ferramentas aceitam conexões e mostram as mensagens sem entregá‑las à Internet.

Exemplo de configuração

Depois de iniciar o capturador, aponte o Nodemailer para localhost e a porta informada pela ferramenta:

const nodemailer = require('nodemailer');

const devTransport = nodemailer.createTransport({
host: '127.0.0.1', // explicite IPv4 se quiser evitar ::1
port: 2525,
secure: false,
tls: { rejectUnauthorized: false } // comum em ferramentas locais
});

await devTransport.verify();
await devTransport.sendMail({
from: 'dev\@localhost',
to: 'qa\@localhost',
subject: 'Teste local',
text: 'Mensagem capturada pelo SMTP fake'
}); 

Importante: use isso apenas para testes. Para envio real a destinatários externos, continue utilizando um provedor SMTP remoto.

Por que as portas locais não respondem

Sem um servidor SMTP rodando localmente, qualquer tentativa de se conectar a localhost:25, localhost:465, localhost:587 ou localhost:2525 resultará em ECONNREFUSED. Esse comportamento é esperado e independe de existir ou não um “serviço SMTP nativo” no Windows 11.

Além disso, quando “localhost” é resolvido para ::1, a conexão tenta o loopback IPv6. Se não houver nada escutando nessa pilha, a recusa será imediata. Ao usar ferramentas locais, prefira 127.0.0.1 para forçar IPv4, caso perceba divergências entre pilhas.

Boas práticas de implementação

Variáveis de ambiente e segurança

  • Mantenha host, port, secure, user e pass fora do código-fonte, em variáveis de ambiente.
  • Evite expor credenciais em repositórios. Considere rotacionar senhas periodicamente.
  • Para provedores que suportam OAuth2, avalie o uso quando apropriado.
# .env
SMTP_HOST=sandbox.smtp.mailtrap.io
SMTP_PORT=2525
SMTP_SECURE=false
SMTPUSER=seuuser
SMTPPASS=suasenha
FROM_ADDR=no-reply@exemplo.com
require('dotenv').config();
const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: Number(process.env.SMTP_PORT),
  secure: String(process.env.SMTP_SECURE).toLowerCase() === 'true',
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS
  },
  logger: true,
  debug: true
});

async function sendExample() {
  await transporter.verify();
  return transporter.sendMail({
    from: process.env.FROM_ADDR,
    to: 'destino@exemplo.com',
    subject: 'Envio com variáveis de ambiente',
    text: 'Este é um teste real via provedor SMTP remoto.'
  });
}

sendExample().catch(console.error);

Pooling e eficiência

Evite criar um novo transporte a cada envio. Centralize uma única instância reusável com pool: true quando houver alto volume.

const transporter = nodemailer.createTransport({
  host: process.env.SMTP_HOST,
  port: Number(process.env.SMTP_PORT),
  secure: false,
  auth: { user: process.env.SMTPUSER, pass: process.env.SMTPPASS },
  pool: true,              // reuso de conexões
  maxConnections: 5,
  maxMessages: Infinity
});

Perguntas frequentes

Preciso de um serviço SMTP local para usar o Nodemailer?
Não. O fluxo recomendado é conectar‑se a um provedor SMTP remoto (Mailtrap para sandbox; Outlook, Gmail, SendGrid e outros para produção).

Por que vejo “SMTP service is missing on Windows 11”?
Porque você procurou um serviço SMTP no services.msc que não existe no Windows 11 cliente. Isso não impede o uso do Nodemailer com servidores remotos.

O que significa ECONNREFUSED ::1:587?
Significa que houve tentativa de conexão ao loopback local na porta 587 e não havia nada escutando. A correção é apontar para o host do provedor real, não para localhost.

Devo desativar IPv6 para evitar ::1?
Não. IPv6 não é o problema. O ponto é usar o host correto. Se estiver testando um SMTP local, use 127.0.0.1 explicitamente para forçar IPv4, caso necessário.

Posso usar Gmail ou Outlook?
Sim. Configure host, porta e segurança conforme o provedor. Em contas com múltiplos fatores, utilize o mecanismo suportado (como senhas de aplicativo ou OAuth2). Evite armazenar credenciais em claro.

Como saber se o firewall está bloqueando?
Se Test-NetConnection <host> -Port <porta> retornar false e a rede estiver funcional, revise regras de saída do firewall e políticas do antivírus ou proxy corporativo.

Resumo prático

  • Windows 11 não possui serviço SMTP embutido — e você não precisa dele para usar Nodemailer.
  • ECONNREFUSED ::1:587 indica tentativa local em porta sem serviço; corrija o host para o do provedor.
  • Valide com transporter.verify() e Test-NetConnection.
  • Para testes locais, use um “fake SMTP” (smtp4dev, Papercut, MailHog) e aponte para localhost.
  • Respeite a relação porta ↔ TLS: 587 com secure:false (STARTTLS), 465 com secure:true.

Conclusão

O erro “SMTP service is missing on Windows 11” não é um bloqueio para o seu projeto com Nodemailer. Ele apenas revela uma suposição incorreta: a de que é preciso um SMTP local no Windows para enviar e‑mails. Ajuste seu transport para o servidor remoto, confirme conectividade e TLS, e — se quiser observar mensagens em ambiente de desenvolvimento — use um capturador local. Com isso, os envios passarão a funcionar de forma confiável, previsível e segura.

Índice