Bounce Management: Complete Technical Guide

Soft bounce vs hard bounce handling, SMTP retry logic, bounce categorization, and automated suppression workflows

Understanding Bounce Types

Bounce management is critical for maintaining sender reputation. Every bounce sends a signal to ISPs about list quality and sending practices. Mishandling bounces—particularly continuing to send to addresses that have hard bounced—is one of the fastest ways to damage IP reputation.

Hard Bounce

Permanent delivery failure. The recipient's email address is invalid, the domain no longer exists, or the server has permanently rejected mail. Hard bounces must be removed from sending lists immediately—continuing to send to these addresses signals spam behavior to ISPs.

Common causes: Typo in email address, closed account, non-existent domain, server explicitly refusing mail

Soft Bounce

Temporary delivery failure. The email was initially accepted but couldn't be delivered due to a recoverable issue. Soft bounces should be retried according to a policy but removed after multiple failures.

Common causes: Mailbox full, server busy, message too large, content filtering

Block (Technical Rejection)

Server is actively rejecting mail, often due to reputation issues. This is the most serious bounce type and requires immediate investigation. Blocks indicate your IP or domain is on a blacklist or has severe reputation problems.

Common causes: IP on blacklist, SPF/DKIM failure, DMARC policy rejection, ISP filtering

SMTP Bounce Codes

Understanding SMTP enhanced status codes is essential for proper bounce categorization and automated handling.

Code Meaning Type Action
550 5.1.1 User unknown Hard Immediate suppression
550 5.1.2 Host unknown Hard Immediate suppression
550 5.1.10 Policy action not permitted Block Investigate, check authentication
450 4.1.2 Recipient address soft bounce Soft Retry with backoff
450 4.2.0 Mailbox temporarily unavailable Soft Retry later
452 4.2.2 Mailbox full Soft Retry, then suppress
554 5.6.0 Invalid message content Block Review content, check formatting

📡 Enhanced Status Code Structure

SMTP codes follow format: Class.Subject.Detail (e.g., 5.1.1 = permanent failure, mailbox unknown).
Class: 4.x.x = temporary (soft), 5.x.x = permanent (hard)
Subject: 1=address, 2=mailbox, 3=system, 4=network, 5=security, 6=protocol

Retry Logic and Policies

Not all soft bounces should be retried immediately. Proper retry logic implements exponential backoff to avoid overwhelming temporarily overloaded servers.

Retry Schedule Algorithm

// Exponential backoff retry scheduler const RETRY_CONFIG = { maxRetries: 4, baseDelay: 15, // minutes maxDelay: 1440, // 24 hours backoffMultiplier: 2 }; function calculateNextRetry(attemptCount, lastAttempt) { const delayMinutes = Math.min( RETRY_CONFIG.baseDelay * (RETRY_CONFIG.backoffMultiplier ** attemptCount), RETRY_CONFIG.maxDelay ); return new Date(lastAttempt.getTime() + delayMinutes * 60000); } // Retry decision matrix function shouldRetry(bounceCode, attemptCount) { if (bounceCode.startsWith("5.")) return false; // Permanent - no retry if (bounceCode.startsWith("4.") && attemptCount < RETRY_CONFIG.maxRetries) return true; return false; }

Retry Decision Flow

// Bounce event handler function handleBounce(emailAddress, bounceResponse, smtpResponse) { const bounceType = classifyBounce(smtpResponse); const bounceCode = extractEnhancedCode(smtpResponse); if (bounceType === "hard") { // Immediate suppression - never retry suppressAddress(emailAddress, { reason: "hard_bounce", code: bounceCode, timestamp: new Date() }); updateListStats("hard_bounce"); } else if (bounceType === "soft") { if (shouldRetry(bounceCode, currentAttemptCount)) { const nextRetry = calculateNextRetry(currentAttemptCount, new Date()); scheduleRetry(emailAddress, nextRetry); } else { // Max retries exceeded - suppress suppressAddress(emailAddress, { reason: "soft_bounce_max_retries", code: bounceCode, attempts: currentAttemptCount }); } } else if (bounceType === "block") { // Investigate before any more sends quarantineIPForInvestigation(sendingIP); alertOperations("Block detected - investigation required"); } }

Suppression List Management

Suppression lists protect sender reputation by preventing further sends to addresses that have already bounced. They should be maintained separately from normal list management and applied at campaign send time, not just at bounce detection.

Suppression Entry Schema

// Suppression list entry { email: "bounced@example.com", reason: "hard_bounce" | "soft_bounce_max_retries" | "complaint" | "unsubscribe", code: "550 5.1.1", // Original SMTP response firstSeen: "2026-01-15T10:30:00Z", lastSeen: "2026-01-15T10:30:00Z", suppressionCount: 1, // Times we suppressed send attempts expiresAt: "2027-01-15T10:30:00Z" // Auto-cleanup after 1 year }

Applying Suppression at Send Time

async function sendCampaignEmail(recipient, campaignId) { // Check suppression before anything else const suppression = await checkSuppressionList(recipient); if (suppression) { logSuppressedSend(recipient, campaignId, suppression.reason); return { status: "suppressed", reason: suppression.reason }; } // Proceed with send... return await deliverEmail(recipient, campaignId); }

⚠️ Suppression vs List Removal

Do NOT simply delete bounced addresses from your list. Suppression is different: the address stays in your system but is flagged so you don't attempt to send again. Some addresses may appear to "recover" (mailbox was full, now isn't) but standard practice is to never retry these without explicit re-permission.

Bounce Rate Thresholds by ISP

Exceeding these thresholds will result in ISP filtering or blacklisting:

ISP Hard Bounce Limit Soft Bounce Limit Total Bounce Limit
Gmail 0.5% 2.0% 2.5%
Outlook 1.0% 3.0% 4.0%
Yahoo 0.8% 2.5% 3.3%
iCloud 0.3% 1.5% 1.8%
AOL 1.0% 3.0% 4.0%

CloudMails Bounce Management

CloudMails infrastructure includes automated bounce handling:

  • Real-time bounce classification using enhanced SMTP codes
  • Automatic suppression list updates
  • Configurable retry policies with exponential backoff
  • Per-ISP threshold monitoring with automatic throttling
  • Bounce analytics dashboard with trend analysis
  • Webhook notifications for hard bounces

Get Bounce Management Infrastructure →