Node.js Bounce Handling Code Example 2026
Handle email bounces in Node.js with a real-world code example. Learn how to parse SMTP replies, manage webhook events, and clean your list using express.
Why Bounce Handling in Node.js Matters for List Hygiene
You send an email campaign. It looks perfect. But a third of your list bounces—hard, soft, or silently. Your inbox placement drops. Your sender reputation tank. And you’re left wondering why.
Bounces aren’t just noise. They’re a signal. Left unhandled, they degrade sender reputation, trigger spam filters, and waste every send after the first. In Node.js, where email workflows are often automated at scale, bounce handling is not a side task—it’s a core part of list hygiene.
This guide walks through a realistic Node.js bounce handling code example that catches, classifies, and acts on bounces using SMTP response codes and common delivery failure patterns. It shows how to maintain clean lists, avoid blacklists, and protect deliverability—especially when integrating with tools like SendGrid, Mailchimp, or raw SMTP servers.
Key takeaways
- Hard bounces in Node.js must be immediately removed from your email list to avoid damaging sender reputation.
- Soft bounces should be tracked and retried only up to a defined limit—typically 3 attempts—before suppression.
- A proper system uses SMTP response codes (like 550 for invalid address, 450 for temporary failure) to classify and react to delivery issues in real time.
What Is a Bounce, and Why Does It Matter for Your Email List?
A bounce happens when an email can't reach its intended recipient’s server. Hard bounces—like invalid addresses—must be removed right away. Soft bounces—such as full inboxes or temporary blocks—should be monitored but not deleted immediately. Ignoring bounces increases spam trap risks, hurts sender reputation, and reduces inbox placement over time. This erodes deliverability and wastes sends.
- Understand that a bounce means the recipient’s server rejected your email—either permanently (hard bounce) or temporarily (soft bounce).
- Hard bounces occur when an address doesn’t exist, is misspelled, or the domain doesn’t exist. You must remove these from your list immediately—any delay increases spam trap exposure.
- Soft bounces happen due to temporary issues: a full inbox, server overload, or greylisting. These are not failures of the address itself, so they don’t need immediate removal.
- Track soft bounces over time. A single soft bounce is okay. Multiple consecutive soft bounces on the same address may signal a real issue—consider deprioritizing or removing the address.
- Let’s be clear: ignoring bounces harms your sender reputation. Internet providers like Gmail or Outlook track bounce rates. High bounce rates correlate strongly with spam filtering and lower inbox placement.
- Use your email service provider’s (ESP) bounce reporting. Most senders expose bounce data via SMTP delivery status codes—check for 5xx responses (permanent) or 4xx (temporary).
- For Node.js applications, parse these codes in your delivery feedback loop. Map 550, 551, 552, 553, 554, and 556 to hard bounces. Treat 4xx codes as soft bounces and queue reattempts or flag for monitoring.
- Consider integrating an email verification tool early to prevent bounces before they happen. Tools like bulk verification help identify invalid addresses before your send.
- Monitor list hygiene continuously. Even valid addresses can become invalid. Regular list cleaning protects deliverability and reduces bounce rates over time.
- Use real-time APIs to check addresses during sign-up—e.g., via the EmailListChecker API. This prevents new invalid addresses from being added in the first place.
Why Bounce Handling Is Part of Deliverability, Not Just Error Checking
Bounce handling isn’t just about avoiding failed sends. It’s foundational to maintaining sender reputation. High bounce rates signal poor list quality, which providers interpret as spam-like behavior. Even if your content is strong, consistent bounces lead to throttling or filtering. This is why major deliverability providers like Spamhaus and MXToolbox track bounce trends as part of reputation scoring.
Over time, unchecked bounces degrade trust with mailbox providers. That means more messages land in spam or are silently dropped. You’re not just losing engagement—you’re damaging long-term deliverability. The solution? Automate detection, classify bounces correctly, and act fast on hard failures. That’s how you stay on the inbox side.
How to Identify Bounce Types in SMTP Responses
You can identify bounce types by parsing SMTP response codes: 5xx codes mean permanent failures (hard bounces), like a user not existing or a mailbox full. 4xx codes indicate temporary issues (soft bounces), such as a full inbox or server overload. Using these codes helps route bounces to the right logic—remove hard bounces immediately, retry soft bounces with delays. The RFC 5321 specification defines these codes in detail.
Decoding SMTP Response Codes
Every bounce response from an SMTP server includes a three-digit code. These are standardized and governed by internet protocols. The first digit determines the general category: 5xx means permanent failure, 4xx means temporary failure, and 2xx means success.
| Code | Bounce Type | Meaning | Recommended Action |
|---|---|---|---|
| 550 | Hard bounce | User unknown or mailbox does not exist | Remove from list immediately |
| 551 | Hard bounce | User not local; mail relayed or moved | Remove unless you have a forward path |
| 552 | Hard bounce | Mailbox full or quota exceeded | Re-attempt after a delay, but remove if persistent |
| 450 | Soft bounce | Mailbox unavailable (temporary) | Queue a retry with exponential backoff |
| 451 | Soft bounce | Temporary processing failure | Wait and retry; don’t block the sender |
| 421 | Soft bounce | Server too busy or service unavailable | Back off and retry later; avoid spam flags |
The full list of standard SMTP response codes is maintained by the IETF. You can find the official definitions in RFC 5321, which governs SMTP behavior.
Routing Bounces in Your Node.js Application
When you receive a bounce in your Node.js app, extract the code and route accordingly. You can use a switch statement or a mapping object to trigger actions based on the code. For example, if you get 550, mark the email as invalid and delete it from your database.
For soft bounces, track them per email. If the same address fails three times in a row, treat it as a hard bounce and remove it. This helps avoid sending to invalid yet temporarily unreachable addresses. Tools like bulk email verification or the real-time verification API can help identify these issues before delivery. These systems use SMTP checks and pattern analysis to catch bounces early.
Node.js Bounce Parser: Real Code Example for SMTP Replies
You can parse SMTP bounce responses in Node.js using a regex or a library like smtp-reply-parser to extract status codes, reasons, and recipients. This lets you distinguish hard bounces (like 550 5.1.1) from soft ones, enabling automated list hygiene. For example, 550 5.1.1 <[email protected]>: Recipient address rejected: User not found indicates a hard bounce — the address is invalid and should be removed immediately.
Step-by-Step Bounce Handling Process
- Install and import a parser like
smtp-reply-parserto reliably decode SMTP response lines. Raw responses vary by system, so using a tested library avoids manual parsing errors and handles edge cases like missing spaces or non-standard wording. - Extract the status code using a regex like
/^(\d{3})\s/from the reply. The first three digits (e.g.,550) define the bounce type:5xxmeans permanent failure,4xxmeans temporary (retry later), and2xxmeans success. This aligns with RFC 5321's SMTP status code standards. - Parse the reason code (e.g.,
5.1.1) to narrow down the error.5.1.1specifically means "User unknown" — a hard bounce. These sub-codes are standardized by RFC 3463, which defines semantic meaning for delivery failures. - Identify the recipient email from the response text. Use a simple regex like
/<([^>]+)>/to capture the address in angle brackets. This helps you track which email failed and why, which is essential for maintaining accurate sender-reputation records. - Classify the bounce severity based on code and reason. A
550 5.1.1is a hard bounce — remove the address permanently. A450 4.2.1might be a temporary issue (e.g., mailbox full), so retry later and update your sending schedule accordingly.
Example Implementation
Here’s a real-world example using smtp-reply-parser:
const parse = require('smtp-reply-parser');
const response = '550 5.1.1 <[email protected]>: Recipient address rejected: User not found';
const parsed = parse(response);
console.log(parsed.statusCode); // 550
console.log(parsed.rejectionCode); // 5.1.1
console.log(parsed.recipient); // [email protected]
Use this structured output to flag invalid emails before sending. You can automate this with middleware that filters bounces before they affect your sender reputation. For large lists, combining this with bulk email verification reduces bounce rates and improves inbox placement over time.
For real-time validation, consider integrating our Node.js-ready API — it checks email syntax, syntax, domain validity, and mailbox existence all in one call, preventing bounces before they happen.
Node.js Webhook Handler: Building an Express Endpoint for Bounce Notifications
You can set up an Express route to receive bounce reports from SendGrid, Mailgun, or similar providers by creating a secure endpoint with body parsing, source validation via webhook signing key or IP whitelist, and forwarding bounce data to your list hygiene system. This keeps your email list clean and improves deliverability.
Step-by-step: Set up your Express webhook endpoint
- Create the route with Express. Use
app.post('/webhook/bounce', ...)to define a dedicated path. This isolates incoming bounce data from other traffic and keeps your server logic clean. - Parse incoming payloads safely. Use
body-parser.urlencoded({ extended: false })orexpress.json()to ensure the request body is processed without injection risks. Never trust raw data from untrusted sources. - Validate the sender’s identity. Providers like SendGrid and Mailgun sign webhooks using HMAC or include known IPs. Check the signature with a shared secret or verify the source IP against a trusted list. This prevents fake bounce reports.
- Forward bounce data to your hygiene engine. Extract the email address and delivery status from the payload. Use your internal system or a service like bulk email verification to flag invalid or risky addresses.
Why this matters for deliverability
Unprocessed bounces lead to degraded sender reputation. Even a 1% bounce rate can trigger filtering. By handling bounces in real time, you avoid sending to invalid or blocked addresses, reducing the risk of being blacklisted by networks like Spamhaus.
Webhook validation is not optional. Without it, attackers can flood your system with fake feedback. Industry standards — such as those outlined in RFC 5322 — reinforce that email infrastructure must authenticate message sources. This protects your domain reputation and ensures only real feedback is processed.
Once validated, your hygiene engine can take action: suppress the email, re-verify it via an API, or retire it from future sends. This feedback loop is essential for maintaining inbox placement over time.
For teams using platforms like SendGrid, Mailgun, or AWS SES, webhook integration is a standard practice. It complements other tools like inbox placement testing to audit how your messages behave in real inboxes.
“A clean list is more important than a large one. Bounce handling is the foundation of sustainable email delivery.”
Mailparser Bounce: Parsing Bounce Notifications from Email Headers
You can extract the original recipient and delivery status from bounce emails using mailparser by inspecting headers like Original-Recipient, Final-Recipient, and X-Failed-Recipients. The Diagnostic-Code or Status field reveals the failure reason. This works reliably with auto-generated bounce messages from MTAs like Exim, Postfix, and Sendmail.
Extracting Key Bounce Data
When an email bounces, the MTA generates a delivery notification. These messages contain structured headers that tell you exactly which address failed and why. You can parse them in Node.js using mailparser—a robust library that handles MIME parsing, including complex bounce formats.
Original-Recipient and Final-Recipient fields often contain the email address that was attempted. Return-Path usually matches the envelope sender, which is critical for validating sender reputation. X-Failed-Recipients sometimes lists multiple failed addresses in a single notification, especially in bulk campaigns.
Reading the Failure Reason
The Diagnostic-Code, often included in the body of a bounce message, holds the most precise failure reason. For example, 550 5.1.1 User unknown means the recipient account doesn't exist. Some bounces include this code in the Status header instead. Both sources are worth checking.
While the exact format varies across MTAs, common failure codes follow SMTP standard conventions. The RFC 3463 defines the structure of delivery status notifications, which underpins most bounce messages. This makes the parsing logic reusable across different email systems.
Let’s say you receive a bounce with Diagnostic-Code: 550 5.1.1: Recipient address rejected: User unknown. In code, you’d extract the 5.1.1 code, match it to a known failure type, and mark the email as invalid. This is where mailparser shines—you don’t have to regex parse raw email bodies.
To reduce bounces in the first place, clean your list before sending. You can verify large lists in seconds using email validation tools. Check real-time delivery health with inbox placement testing, or verify individual addresses instantly via our verification API. For bulk list cleanup, try bulk verification with 98.9% accuracy.
Integrating Real-Time Verification to Prevent Bounces Before They Happen
You can prevent bounces before they happen by integrating real-time email verification into your Node.js workflow. Using an API like Emaillistchecker.io, you validate addresses instantly—checking syntax, domain reachability, and mailbox existence—before sending. This stops invalid, role-based, and disposable emails from ever hitting your mail server. It’s an industry-standard safeguard for maintainable sender reputation.
How it works in practice
- Before dispatching emails, call Emaillistchecker.io’s verification API from your Node.js code to validate each address in bulk.
- Filter out any email flagged as “invalid” or “catch-all” — these either don’t exist or accept all messages without verification.
- Exclude disposable domains (like tempmail.org or mailinator.com) that are used for temporary signups and often result in failed deliveries.
- Block role accounts (such as admin@, support@, info@) that commonly bounce or go unread, harming your sender score over time.
- Use the API’s high accuracy — 98.9% proven through real-world validation across domains, subnets, and mail server behaviors — to minimize false negatives.
Code example: basic integration
Here’s a minimal Node.js snippet using the Emaillistchecker.io API to vet a single email address before sending:
const https = require('https');
const querystring = require('querystring');
const verifyEmail = (email) => {
const data = querystring.stringify({ email, api_key: 'your_api_key' });
const options = {
hostname: 'api.emaillistchecker.io',
path: '/verify',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': data.length
}
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let body = '';
res.on('data', (chunk) => body += chunk);
res.on('end', () => {
const result = JSON.parse(body);
resolve(result.status === 'valid' ? true : false);
});
});
req.on('error', reject);
req.write(data);
req.end();
});
};
// Usage
verifyEmail('[email protected]').then(isValid => {
if (!isValid) {
console.log('Rejected: invalid email');
}
});
For larger lists, use the bulk verification tool to process thousands of addresses at once. This is not a replacement for SMTP error handling, but a preventive layer. Even with perfect syntax and a clean mailbox, messages to disposable or role accounts still hurt inbox placement.
By catching these issues early, you reduce hard bounces (which degrade sender reputation), avoid blacklists, and improve long-term deliverability. This is how real deliverability teams build sustainable email flows.
“An ounce of prevention is worth a pound of remediation” — and in email, that ounce is real-time validation.
How Emaillistchecker.io Fits into Your Node.js Bounce Prevention Stack
Integrate Emaillistchecker.io’s real-time API and bulk tools into your Node.js workflow to catch invalid, risky, or disposable emails before they hit your mail server—reducing hard bounces by up to 80% and improving inbox placement. You’re not just filtering spam; you’re building a cleaner, more trustworthy sending list from the start.
Run Pre-Send Verification with the API
Let’s say you’re building a Node.js app that sends transactional or campaign emails. Instead of relying on post-send bounce analysis, insert an API call to Emaillistchecker.io’s verification API right before dispatch. This checks each address in real time for syntax, domain validity, and mailbox existence—catching over 90% of invalid or inactive addresses before they’re sent.
This approach aligns with industry standards like RFC 5321 and RFC 5322, which define acceptable email formats and delivery rules. Skipping this step increases the risk of being flagged as a spam source, especially when your sender reputation depends on consistent deliverability.
Clean and Monitor at Scale
For existing lists, run a full scan through the bulk verification tool. This process can identify catch-all domains, disposable emails, and role accounts—common causes of soft bounces or delivery failure. Cleaning a 10,000-email list before a campaign can reduce bounce rates from 10% to under 2% in practice.
Pair this with inbox-placement testing to see how your emails actually land across Gmail, Outlook, and Apple Mail. Combine this with real-time verification to build a feedback loop: your Node.js app sends checks, learns from results, and adjusts its list hygiene policy over time.
When you encounter complex bounce patterns—like intermittent delivery failures or recurring timeouts—the in-app AI assistant can help decode domain behavior. For example, it can flag a domain that appears healthy but is known to run greylisting or catch-all systems, which aren’t immediately obvious in SMTP responses.
Even small improvements in list hygiene directly correlate with lower bounce rates and better sender reputation, per data from Return Path’s annual email deliverability reports.
Best Practices for Bounce Handling in Node.js: What to Avoid
You shouldn’t retry hard-bounced addresses, ignore repeated soft bounces, rely only on parsing bounce emails, or assume every bounce means an invalid address. These mistakes hurt deliverability, harm sender reputation, and waste bandwidth. Let’s break down exactly what not to do—and why.
What Not to Do: Critical Mistakes in Bounce Handling
- Never retry sending to a hard-bounced address. A hard bounce means the recipient’s email server permanently rejected the message. Repeated attempts signal spam behavior and can get your domain blacklisted. RFC 6522 outlines sender responsibilities, including respecting permanent failures.
- Avoid ignoring soft bounces from the same recipient across multiple sends. A single soft bounce might mean a full inbox, but repeated ones suggest a broader delivery failure. Track and flag these accounts to avoid future waste.
- Do not rely solely on parsing bounce emails. Bounce messages vary wildly between ESPs and aren’t standardized. You’ll miss patterns, misclassify issues, and delay remediation. Use API-level reporting from your email service provider (ESP) for real-time, structured insights.
- Never assume all bounces are from invalid addresses. Many are caused by temporary issues like server overload, message size limits, or rate limiting. Automatically marking these as invalid damages list hygiene and leads to false negatives. Let your system distinguish between temporary and permanent failures.
When to Trust the Source: Beyond Parsing
While parsing bounce emails is common, it’s error-prone. Some providers encode bounce reasons in headers, while others deliver generic error codes. The result? Misclassified bounces, poor list hygiene, and degraded sender reputation. Instead, integrate with your ESP’s delivery dashboard or webhooks to receive structured data. Use real-time email verification via our API to catch issues before they trigger bounces at all. You're not just reacting—you're preventing.
Ultimately, bounce handling isn’t about catching every failure. It’s about understanding each type, acting with precision, and not letting your outbound traffic harm your long-term reputation. A smart system reduces hard bounces, catches misclassified soft bounces early, and keeps your list clean—all before the first message ever leaves your server.
Tracking Bounces with a Logging and Alert System
You can track email bounces in Node.js by logging each bounce with recipient, timestamp, reason, severity, and source service. Use this data to spot patterns—like repeated failures from one domain or sudden spikes in blocking—and trigger alerts. This helps identify spam traps, role accounts, or compromised inboxes before they harm sender reputation.
Step-by-step bounce tracking process
- Record bounce data in a structured format when your email service returns a delivery failure. Store the recipient email, exact timestamp, bounce reason (e.g., “550 5.1.1 User unknown”), severity level (temporary vs. permanent), and the sending service (e.g., SendGrid, AWS SES). This consistency enables later analysis and correlation across campaigns.
- Map each bounce reason to a severity tier (e.g., 1 = temporary delay, 5 = permanent hard bounce). Use established standards like RFC 3463 or the SMTP status codes defined in RFC 5321 to classify outcomes uniformly. This prevents misinterpretation when reviewing logs at scale.
- Set up thresholds for repeated bounces from the same domain or IP range. For example, log any domain with more than 3 hard bounces in a 24-hour window. This catches mass inboxes or compromised accounts being used to receive mail, which can indicate spam traps or phishing patterns.
- Integrate alerts via webhook or email when thresholds are met. Use services like Slack or PagerDuty to notify your team when a suspicious pattern emerges. Monitoring tools like Mail-Tester can validate bounce handling logic, though they won’t automate alerts for you.
- Review logs monthly to detect anomalies like role accounts (e.g., admin@, postmaster@) consistently receiving your mail. These are often low-engagement, high-failure recipients. Also flag inboxes that were once valid but now reject messages—possible signs of hijacking or domain policy changes.
Why this approach works
Without logs, bounces vanish into the void. With structured tracking, you turn every failure into a data point for sender reputation defense. Role accounts, while valid, don’t open emails—sending to them hurts your inbox placement. Similarly, catching spam traps early prevents blacklisting.
For bulk operations, preemptive verification reduces bounce risk before sending. Use bulk verification with tools that check syntax, domain validity, and mailbox existence—including catch-all detection—so your Node.js system only processes known-good addresses.
Conclusion: Clean Lists Start with Code That Handles Bounces Correctly
Bounce handling in Node.js isn’t just about catching errors—it’s about building a system that respects SMTP protocols, parses response codes accurately, and acts on feedback in real time.
Using tools like Emaillistchecker.io to verify addresses early and reliably reduces bounce rates before messages even leave your server, protecting sender reputation and improving long-term inbox placement.
Consistent email hygiene isn’t optional. It’s the foundation of sustainable deliverability, and it starts with correct code and accurate data.
Sources
- The average email bounce rate across all industries is 2.48%, based on combined Mailchimp and Campaign Monitor data covering more than 30 billion emails. — WebFX (Mailchimp & Campaign Monitor data) (2026)
- Mailchimp's platform-wide data puts the average hard bounce rate at just 0.21% and the soft bounce rate at 0.70%, meaning well-maintained lists bounce under 1% in total. — Verified.email (Mailchimp data via Mailerio) (2025)
Keep reading
- Email bounces: codes, causes and prevention (complete guide)
- SMTP Bounce Code Cheat Sheet for Developers in 2026
- rxjs debounceTime switchmap Email Validation in Angular 2026
- Python Bounce Email Parser Example for List Hygiene in 2026
- Greylisting Bounce How to Handle 451 Retries in 2026
Ready to put this into practice? Emaillistchecker.io verifies emails with 98.9% accuracy — start with 100 free verifications.
Frequently asked questions
How do I parse a bounce notification in Node.js?
Use the `mailparser` library to extract headers like `Original-Recipient` and `Diagnostic-Code`, then map the status code to hard/soft bounce logic.
What is a hard bounce in SMTP?
A hard bounce is a permanent delivery failure, commonly due to invalid email addresses or non-existent domains. It must be removed from your list immediately.
Can I handle bounces without a webhook?
Yes, but it’s less efficient. You can parse bounce emails manually or use server logs. Webhooks provide faster, automated detection.
How often should I clean my email list?
Run list hygiene checks quarterly at minimum. Clean your list after every major campaign and integrate real-time verification for ongoing maintenance.
What's the difference between a catch-all and a risky email?
A catch-all accepts all emails, even invalid ones. A risky address may be role-based, disposable, or have a poor reputation—both should be excluded.
Does Emaillistchecker.io support bulk list verification?
Yes. It offers bulk verification with 98.9% accuracy, supports integrations with Mailchimp, SendGrid, and others, and provides real-time API access.
How does email verification reduce bounce rates?
By identifying invalid, disposable, and role accounts before sending, it prevents delivery failures and protects sender reputation.
What is the best way to prevent role-based address bounces?
Use email verification tools that flag common role addresses like admin@, sales@, or info@, which are often catch-alls or inactive.
Can I use Emaillistchecker.io with Express and SendGrid?
Yes. The service integrates directly with SendGrid, Mailchimp, Klaviyo, and HubSpot, and supports real-time API calls from Express servers.
What happens if I ignore soft bounces?
Repeated soft bounces indicate temporary server issues or overloading. Ignoring them can lead to delivery throttling or blacklisting by the recipient’s server.
How do I know if an email is disposable?
Use a verification service like Emaillistchecker.io that checks against known disposable domain lists and flags them during validation.
Do I need to verify emails on every campaign?
Yes, especially for large lists or new domains. Real-time verification before each send ensures your list stays clean and deliverable.