Su Windows 11, Nodemailer può fallire con l’errore ECONNREFUSED ::1:587 (o 25/465/2525) perché non esiste più un server SMTP locale preinstallato. In questa guida spiego la causa, le opzioni per inviare email e i passaggi rapidi per risolvere, con esempi pronti da copiare.
Perché vedi “ECONNREFUSED ::1:587” con Nodemailer su Windows 11
L’errore ECONNREFUSED
indica che la connessione TCP è stata rifiutata all’istante dall’host di destinazione: non c’è nessun processo in ascolto sulla porta indicata. Il dettaglio ::1
è il loopback IPv6 (equivalente IPv6 di 127.0.0.1
). In breve, il tuo script sta provando a collegarsi a localhost
sulla porta SMTP (587, 25, 465 o 2525), ma su Windows 11 non c’è alcun demone SMTP attivo e quindi il sistema rifiuta la connessione.
Segnali tipici
ECONNREFUSED ::1:587
(o::1:25
,::1:2525
,::1:465
).telnet localhost 587
oTest-NetConnection -ComputerName localhost -Port 587
falliscono.- In
services.msc
non trovi alcun “Simple Mail Transfer Protocol (SMTP)”.
Nota su “ping” delle porte
ping
usa ICMP e non “vede” le porte TCP: è normale che “pingare” localhost
non dica nulla sulla disponibilità di :587
. Per testare una porta usa Test-NetConnection
(PowerShell) o telnet
(cliente opzionale) o, in alternativa, openssl s_client
per test TLS.
Causa radice: cambiamento in Windows 11
- Windows 11 non include più il vecchio “SMTP Service” (in passato parte di IIS). Di conseguenza, su un’installazione standard non c’è un server SMTP che ascolta su
localhost
. - Il risultato è che qualunque tentativo Nodemailer →
localhost:587
viene rifiutato all’istante (ECONNREFUSED).
Tre strade per inviare email da Node.js su Windows 11
Di seguito trovi una tabella di confronto con pro/contro e istruzioni di massima.
Strategia | Dettagli di implementazione | Pro | Contro |
---|---|---|---|
Usare un provider SMTP esterno (consigliato) | Configura Nodemailer con host , port , auth.user e auth.pass del provider (es. Mailtrap, Gmail, Outlook, SendGrid). | Semplice, affidabile, nessun servizio da mantenere. | Richiede connessione Internet e (talvolta) credenziali/app‑password. |
Server SMTP locale di test | Installa strumenti lightweight come smtp4dev, MailHog, Papercut o MailSlurper (exe o Docker). Poi punta Nodemailer a localhost:1025 (o porta scelta). | Nessun traffico esterno; comodo per debug con interfaccia web. | Solo per test; non spedisce posta reale a Internet senza ulteriore relay. |
Server SMTP “vero” on‑prem | Esegui un MTA completo (es. hMailServer, Postfix su WSL/Docker). | Controllo totale, invii reali anche offline. | Configurazione complessa, apertura porte 25/587 pubbliche, gestione DNS (MX, SPF, DKIM) e rischi di blacklist. |
Riattivare IIS SMTP (sconsigliato) | Disponibile solo su Windows Server, obsoleto e non più mantenuto. | — | Mancanza di aggiornamenti, potenziali falle di sicurezza. |
Percorso consigliato rapido (Mailtrap)
Se il tuo obiettivo è sviluppo e test, usa Mailtrap (o un provider sandbox simile). È già perfettamente integrabile con Nodemailer e ti evita di “riattivare” server locali. Mantieni questa configurazione nel tuo codice:
const nodemailer = require("nodemailer");
const transport = nodemailer.createTransport({
host: "sandbox.smtp.mailtrap.io",
port: 2525,
auth: { user: "…", pass: "…" }
});
// verifica rapida delle credenziali/connessione
transport.verify((err, success) => {
if (err) {
console.error("SMTP non pronto:", err);
} else {
console.log("SMTP pronto, invio consentito.");
}
});
// invio di prova
async function send() {
const info = await transport.sendMail({
from: '"Dev Box" <dev@example.test>',
to: "qa@example.test",
subject: "Prova Nodemailer su Windows 11",
text: "Se leggi questo, l’SMTP funziona.",
html: "<p>Se leggi questo, l’SMTP funziona.</p>"
});
console.log("Messaggio accettato con id:", info.messageId);
}
send().catch(console.error);
Con questa impostazione puoi eseguire in locale: il provider riceverà il messaggio nella sua inbox di test. Non usare localhost
come host finché non hai installato un server in ascolto sulla tua macchina.
Quando passare all’invio reale verso Internet
Per un ambiente di produzione o demo pubblica, configura un provider SMTP reale (Gmail, Outlook/Exchange Online, SendGrid, ecc.). Imposta:
- Porta 465 con
secure: true
(TLS implicito) oppure porta 587 consecure: false
+ STARTTLS. - Autenticazione con app‑password o OAuth2 (a seconda del provider).
- Indirizzo
from:
verificato presso il provider.
// Esempio generico provider "classico"
const transport = nodemailer.createTransport({
host: "smtp.example.com",
port: 587,
secure: false, // STARTTLS su 587
auth: { user: process.env.SMTPUSER, pass: process.env.SMTPPASS }
});
Tip: attiva i log di debug per capire subito cosa succede nello scambio SMTP/TLS:
const transport = nodemailer.createTransport({
host: "sandbox.smtp.mailtrap.io",
port: 2525,
auth: { user: "…", pass: "…" },
logger: true, // stampa log su console
debug: true
});
Alternative: server SMTP locale di test (nessuna posta “vera”)
Se preferisci tenere tutto in locale per il debug, ecco due opzioni leggere e affidabili.
MailHog via Docker
Avvia un finto SMTP e una web UI per leggere le email catturate:
docker run --rm -p 1025:1025 -p 8025:8025 mailhog/mailhog
Punta Nodemailer a localhost:1025
e apri http://localhost:8025
nel browser per vedere le email intercettate.
const transport = nodemailer.createTransport({
host: "localhost",
port: 1025,
secure: false
});
smtp4dev (exe o Docker)
Exe: scarica la versione desktop e scegli la porta SMTP (consiglio 2525 o 1025). L’app offre una UI locale dove leggere i messaggi.
Docker:
docker run --rm -p 2525:25 -p 5000:80 rnwood/smtp4dev
Con questa mappatura, configuri Nodemailer su localhost:2525
e apri la UI su http://localhost:5000
.
Papercut / MailSlurper
Soluzioni analoghe: installi, scegli la porta SMTP (es. 1025/2525) e indirizzi Nodemailer su localhost:porta
. Sono pensate per test/sandbox e non spediscono su Internet senza relay.
Opzione avanzata: MTA “vero” on‑prem (solo se necessario)
Vuoi davvero un server SMTP che invia verso Internet dalla tua macchina? È possibile, ma serve consapevolezza:
- hMailServer (Windows): semplice interfaccia, ma va protetto e correttamente configurato.
- Postfix su WSL/Docker: robusto e flessibile, ma più tecnico.
Attività inevitabili:
- Apertura delle porte 25/465/587 sul firewall/router.
- DNS: record MX per il dominio, oltre a SPF, DKIM, DMARC.
- Gestione del rischio blacklist e reputazione IP (spesso gli ISP bloccano la 25 in uscita).
Per molti team conviene evitare questa strada e delegare a un provider gestito.
Passaggi minimi (riassunto operativo)
- Mantieni Mailtrap (già indicato nel codice):
const transport = nodemailer.createTransport({ host: "sandbox.smtp.mailtrap.io", port: 2525, auth: { user: "…", pass: "…" } });
Invia pure in locale: Mailtrap riceverà i messaggi nella sua inbox di test. - Rimuovi riferimenti a
localhost
finché non hai installato un server SMTP in ascolto. - Controlla firewall/antivirus solo se stai aprendo porte per un server che hai installato; altrimenti non è necessario.
Checklist di diagnosi veloce
- Il tuo host è giusto? Evita
localhost
se stai usando un provider esterno. - La porta è coerente? 465 ⇒
secure: true
; 587 ⇒secure: false
+ STARTTLS; 25 ⇒ spesso filtrata/riservata ai server. - Le credenziali sono corrette? Utente e password del provider, non del tuo account Windows.
- Il from è autorizzato? Molti provider richiedono di verificare il dominio o l’indirizzo mittente.
- Verifica prima di inviare:
await transporter.verify()
.
Comandi utili su Windows 11
Verificare se una porta è in ascolto in locale
Get-NetTCPConnection -LocalPort 1025 -State Listen
oppure
netstat -ano | findstr :1025
Testare la raggiungibilità di un host/porta esterni
Test-NetConnection -ComputerName sandbox.smtp.mailtrap.io -Port 2525
Shortcut:
tnc sandbox.smtp.mailtrap.io -Port 2525
Client Telnet (opzionale)
Se usi telnet
e ottieni “connessione non riuscita”, vuol dire che non c’è nessun server in ascolto su quella porta/host o la rete lo blocca. Ricorda che Telnet non gestisce TLS; per 587 dovrai inviare STARTTLS
a mano (non comodo). Meglio affidarsi a Nodemailer e ai suoi log.
Capire i messaggi d’errore più comuni
- ECONNREFUSED: porta chiusa o nessun servizio in ascolto. Tipico di
localhost
senza server SMTP. - ETIMEDOUT: la connessione non si stabilisce (firewall di rete, filtro ISP, host errato, porta bloccata).
- EAUTH o 535 Authentication failed: credenziali errate o account non abilitato all’SMTP.
- Handshake TLS fallito: porta/secure non coerenti (es.
secure: true
su 587), certificati non validi (solo su server locali auto‑firmati).
IPv4 vs IPv6: perché appare “::1”
Su molte macchine, localhost
risolve prima in IPv6 (::1
). Se hai un server locale che ascolta solo su IPv4 (127.0.0.1
), la connessione può fallire finché non forzi IPv4. Esempio:
// Forza IPv4 verso il server locale di test
const transport = nodemailer.createTransport({
host: "127.0.0.1",
port: 1025,
secure: false
});
Ma ricorda: il problema di base su Windows 11 non è IPv6 in sé, è l’assenza del servizio SMTP di sistema.
Buone pratiche per produzione
- SPF/DKIM/DMARC: configura questi record DNS per evitare spam folder e migliorare la deliverability.
- Rate limiting: i piani gratuiti dei provider hanno limiti (email/ora/giorno). Implementa code o retry con backoff.
- Monitoraggio: logga
messageId
, risposta del server e gestisci i bounce (con webhook/IMAP o API del provider). - Segreti: conserva
SMTPUSER
/SMTPPASS
in variabili d’ambiente o secret manager, non in git. - Timeout e retry: imposta
connectionTimeout
,socketTimeout
e un piano di retry ragionato.
Template di configurazione Nodemailer a prova di errore
const nodemailer = require("nodemailer");
function buildTransport() {
const {
SMTP\_HOST = "sandbox.smtp.mailtrap.io",
SMTP\_PORT = "2525",
SMTP\_USER,
SMTP\_PASS,
SMTP\_SECURE = "false"
} = process.env;
return nodemailer.createTransport({
host: SMTP\_HOST,
port: Number(SMTP\_PORT),
secure: SMTP\_SECURE === "true",
auth: SMTP\USER && SMTP\PASS ? { user: SMTP\USER, pass: SMTP\PASS } : undefined,
logger: true,
debug: true
});
}
async function main() {
const transporter = buildTransport();
try {
await transporter.verify();
console.log("✔️ Trasportatore SMTP verificato.");
} catch (e) {
console.error("❌ Verifica SMTP fallita:", e);
process.exit(1);
}
const info = await transporter.sendMail({
from: '"App" <[no-reply@example.test](mailto:no-reply@example.test)>',
to: "[dev@example.test](mailto:dev@example.test)",
subject: "Test",
text: "Ciao da Nodemailer",
html: "\Ciao da Nodemailer\"
});
console.log("Messaggio inviato:", info.messageId);
}
main().catch(console.error);
FAQ
Posso “riattivare” il vecchio SMTP di IIS su Windows 11?
No. Quell’elemento è legato a Windows Server e, in ogni caso, è obsoleto. Non è una strada sicura.
Il firewall di Windows blocca Mailtrap o MailHog?
Se usi un provider esterno non devi toccare il firewall locale. Se invece instauri un server SMTP sulla tua macchina, allora dovrai aprire la porta scelta (es. 1025/2525) solo per le connessioni locali, non verso Internet.
Il mio ISP blocca la 25 in uscita: come faccio?
Usa 587 (con STARTTLS) o 465 (TLS) del provider. Molti provider offrono anche 2525 come alternativa “developer‑friendly”.
Posso inviare con Gmail senza app‑password o OAuth2?
Dipende dalle policy del tuo account. Le app‑password (con 2FA) o OAuth2 sono l’approccio raccomandato. Evita l’invio con account personale in produzione.
In sintesi
L’errore ECONNREFUSED ::1:587 su Windows 11 non dipende da qualcosa “da reinstallare”, ma dal fatto che il sistema non fornisce più un server SMTP interno. La soluzione più rapida e robusta è usare un provider SMTP esterno (Mailtrap per test, un provider “vero” per produzione). In alternativa, per il debug puoi installare un falso SMTP locale (MailHog, smtp4dev, Papercut). Solo se hai esigenze particolari ha senso mettere in piedi un MTA on‑prem, consapevole di DNS, sicurezza e reputazione.
Appendice: snippet e comandi rapidi
- MailHog (Docker)
docker run --rm -p 1025:1025 -p 8025:8025 mailhog/mailhog
Nodemailer →host: "localhost"
,port: 1025
,secure: false
; UI suhttp://localhost:8025
. - smtp4dev (Docker)
docker run --rm -p 2525:25 -p 5000:80 rnwood/smtp4dev
Nodemailer →host: "localhost"
,port: 2525
; UI suhttp://localhost:5000
. - PowerShell: test di una porta
tnc sandbox.smtp.mailtrap.io -Port 2525
- Verifica Nodemailer
await transport.verify();
Promemoria per la produzione
- Record SPF/DKIM/DMARC corretti.
- TLS attivo (465 o STARTTLS su 587).
- Rate limit e code di invio controllate.
- Log e gestione bounce/complaint.
- Segreti in variabili d’ambiente.
Con questi accorgimenti, passare da “ECONNREFUSED ::1:587” all’invio affidabile di email con Nodemailer su Windows 11 diventa un percorso lineare e ripetibile.
In conclusione: l’errore non dipende da un servizio mancante da reinstallare, ma dal fatto che Windows 11 non fornisce più un server SMTP interno: occorre usare un servizio esterno o installarne uno dedicato. La strategia raccomandata è adottare un provider SMTP esterno (Mailtrap in sviluppo, un provider affidabile in produzione), mantenendo l’infrastruttura semplice, sicura e monitorabile.