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.
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 IPv4127.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 erro | Indicação | Como agir |
---|---|---|
ECONNREFUSED ::1:587 | Tentativa local em porta sem serviço ativo | Trocar o host para o do provedor SMTP remoto |
ETIMEDOUT | Bloqueio de saída, latência ou indisponibilidade | Checar firewall, proxy, VPN e Test-NetConnection |
ENOTFOUND / EAI_AGAIN | Problema de DNS | Verificar Resolve-DnsName e configuração de DNS |
Falha de autenticação | Credenciais incorretas | Revalidar 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ípica | secure | Modo | Observações |
---|---|---|---|
587 | false | STARTTLS | Padrão moderno para submissão autenticada |
465 | true | TLS implícito | Conexão já nasce criptografada |
2525 | false na maioria | Variável por provedor | Porta 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
epass
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()
eTest-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 comsecure: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.