How to configure SMTP connections correctly (421: Service not available error)
What causes the 421 error?
Every SMTP connection follows a set sequence:
1. Connect to MailerSend's mail server
2. Authenticate with your credentials
3. Send recipient info and email data (one email = one transaction)
4. Disconnect
Each connection has a limit of 5 transactions, meaning you can send a maximum of 5 emails per connection. When your software opens a single connection and tries to loop through more than 5 emails before disconnecting, MailerSend closes the connection and returns the 421 error.
This is a common misconfiguration. Many email libraries and sending tools default to reusing a single connection for all outgoing messages, which works fine at low volumes but breaks at scale.
How to fix it
Option 1: Configure your software to open multiple connections
Instead of sending all emails over one connection, configure your software to open a new connection for every batch of up to 5 emails. This is the most reliable fix.
How you do this depends on your sending software. Look for settings like:
Max messages per connection: Set to 5 or fewer
Connection pooling: Enable this so your software manages multiple connections automatically
SMTP session reuse: Disable or limit this setting
If you're not sure where to find these settings, check your software's documentation for "SMTP connection limit" or "max emails per session."
Below are configuration examples for some of the most common sending libraries and tools.
PHPMailer
By default, PHPMailer opens a new connection for every send() call, which is correct. The problem occurs when SMTPKeepAlive is set to true. This keeps one connection alive across all sends in a loop, which will exceed the 5-transaction limit.
If you're sending in a loop with SMTPKeepAlive enabled, you need to manually close and reopen the connection every 5 emails:
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = 'smtp.mailersend.net';
$mail->SMTPAuth = true;
$mail->Username = 'your-username';
$mail->Password = 'your-password';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
// Only enable SMTPKeepAlive if you're managing reconnects manually
$mail->SMTPKeepAlive = true;
$recipients = ['a@example.com', 'b@example.com', /* ... */];
$batchSize = 5; // Stay within MailerSend's 5-transaction limit
foreach ($recipients as $index => $recipient) {
$mail->clearAddresses();
$mail->addAddress($recipient);
$mail->Subject = 'Your subject';
$mail->Body = 'Your message body';
$mail->send();
// Close the connection after every 5 emails and let it reopen on the next send
if (($index + 1) % $batchSize === 0) {
$mail->smtpClose();
}
}
// Always close the connection when done
$mail->smtpClose();
If SMTPKeepAlive is false (the default), PHPMailer reconnects on every send automatically, no batching logic needed. Only add the manual close logic if you've explicitly enabled SMTPKeepAlive.
WordPress + WP Mail SMTP
WP Mail SMTP uses PHPMailer under the hood. WordPress sites typically send low volumes of transactional emails (form submissions, order confirmations, account emails) where each email is triggered individually. This pattern is less likely to hit the connection limit.
If your site sends bursts of emails (for example, notifying many users at once via a plugin), use WP Mail SMTP's built-in rate limiting to spread sends over time:
1. In WP Mail SMTP, go to Settings > Misc.
2. Toggle the Email Rate Limiting option on.
3. Set a limit such as 5 emails per minute to stay comfortably within MailerSend's 120 auth requests/minute ceiling.
This throttles or schedules email sending depending on configuration.
Nodemailer (Node.js)
Nodemailer's default behavior creates a fresh connection per email, which is safe. The issue arises when connection pooling is enabled (pool: true) with maxMessages set higher than 5. With pooling, Nodemailer reuses connections across multiple sends until maxMessages is reached. If that threshold is above 5, you'll exceed MailerSend's limit.
Set maxMessages to 5 to match MailerSend's per-connection transaction limit:
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
host: 'smtp.mailersend.net',
port: 587,
secure: false,
pool: true, // Connection pooling is enabled
maxConnections: 5, // Up to 5 parallel connections (stay under the 120 auth/min limit when combined)
maxMessages: 5, // Close and reopen connection after 5 emails to match MailerSend's limit
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
});
Nodemailer's maxMessages defaults to 100, which will immediately exceed the 5-transaction limit if pooling is on. Always set maxMessages: 5 when using MailerSend's SMTP relay.
smtplib (Python)
Python's smtplib keeps the connection open for as long as the SMTP object exists. If you loop through recipients and call sendmail() more than 5 times on the same connection, you'll hit the limit.
The fix is to reconnect every 5 emails using a batch loop:
import smtplib
import time
from email.mime.text import MIMEText
SMTP_HOST = 'smtp.mailersend.net'
SMTP_PORT = 587
USERNAME = 'your-username'
PASSWORD = 'your-password'
BATCH_SIZE = 5 # MailerSend's transaction limit per connection
recipients = ['a@example.com', 'b@example.com', 'c@example.com'] # your full list
# Split recipients into batches of 5
def chunked(lst, size):
for i in range(0, len(lst), size):
yield lst[i:i + size]
for batch in chunked(recipients, BATCH_SIZE):
with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as smtp:
smtp.starttls()
smtp.login(USERNAME, PASSWORD)
for recipient in batch:
msg = MIMEText('Your message body')
msg['Subject'] = 'Your subject'
msg['From'] = 'you@yourdomain.com'
msg['To'] = recipient
smtp.sendmail('you@yourdomain.com', recipient, msg.as_string())
# Connection closes automatically at end of `with` block
# Optional: add a short delay between batches to avoid hitting auth rate limits
time.sleep(0.5)
Using Python's with statement ensures the connection closes cleanly after each batch. The time.sleep() call helps if you're sending large volumes. Without it, rapid reconnects can trigger the 120 auth requests/minute rate limit.
Django (django.core.mail)
Django's email backend creates a new connection per send_mail() call by default, which is safe. For sending to multiple recipients efficiently, use send_mass_mail() or open a connection manually with get_connection(), but close it every 5 messages:
from django.core.mail import get_connection, EmailMessage
import time
recipients = ['a@example.com', 'b@example.com', 'c@example.com'] # your full list
BATCH_SIZE = 5
def chunked(lst, size):
for i in range(0, len(lst), size):
yield lst[i:i + size]
for batch in chunked(recipients, BATCH_SIZE):
connection = get_connection()
connection.open()
messages = [
EmailMessage(
subject='Your subject',
body='Your message body',
from_email='you@yourdomain.com',
to=[recipient],
connection=connection,
)
for recipient in batch
]
connection.send_messages(messages)
connection.close()
time.sleep(0.5) # Throttle between batches
Jakarta Mail/JavaMail (Java)
The standard Transport.send() pattern in JavaMail opens and closes a connection per email by default, which is safe. The limit is most likely to be hit when a Transport object is reused across many sends in a loop.
Use transport.sendMessage() in batches of 5, closing and reconnecting between batches:
import jakarta.mail.*;
import jakarta.mail.internet.*;
import java.util.*;
public class BatchEmailSender {
private static final int BATCH_SIZE = 5; // MailerSend's transaction limit
public static void main(String[] args) throws Exception {
String host = "smtp.mailersend.net";
String username = "your-username";
String password = "your-password";
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", "587");
Session session = Session.getInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
List recipients = List.of("a@example.com", "b@example.com", "c@example.com");
for (int i = 0; i < recipients.size(); i += BATCH_SIZE) {
List batch = recipients.subList(i, Math.min(i + BATCH_SIZE, recipients.size()));
// Open a fresh connection for each batch
Transport transport = session.getTransport("smtp");
transport.connect(host, username, password);
for (String recipient : batch) {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("you@yourdomain.com"));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));
message.setSubject("Your subject");
message.setText("Your message body");
transport.sendMessage(message, message.getAllRecipients());
}
transport.close(); // Close after each batch of 5
Thread.sleep(500); // Optional: throttle between batches
}
}
}
Option 2: Implement proper send throttling
Even with multiple connections, you'll need to stay within the authentication rate limit of 120 requests per minute. If your software opens connections too quickly, you'll hit a different rate limit.
To stay well within limits:
Introduce a short delay between connection attempts
Don't send all emails simultaneously. Instead, spread them out over time
Use a queue or job system if you're sending large volumes
With correct configuration, you can send up to 600 emails per minute (120 connections × 5 transactions each).
Sending marketing emails
If you're hitting this error because you're sending bulk campaigns, like newsletters, promotional emails, or announcements, MailerSend isn't the right tool for that. Our SMTP relay is designed for transactional emails: password resets, order confirmations, account notifications and other programmatically triggered, one-to-one messages.
For marketing campaigns, use MailerLite instead. It's built for bulk, promotional sending with the features (unsubscribe management, list segmentation, analytics) that marketing emails require. Using our SMTP relay for bulk sends will consistently run into connection and rate limits, regardless of configuration.
Current SMTP limits
Here's a full breakdown of the limits in place:
Connections per IP per minute: 300 per 60 seconds
Transactions per connection: 5 (default)
Failed logins per IP per day: 100
Tracking window: 24 hours
Block duration: 24 hours
Consecutive login fails per username + IP: 10
Tracking window: 90 days
Block duration: 1 hour
Consecutive login requests per username: 120 per 60 seconds
Maximum throughput: 600 emails per minute when correctly configured (120 connections × 5 transactions).
The authentication limit of 120 requests/minute is the effective ceiling. You'll hit this before reaching the 300 connections/minute limit.
What to do if you’re still seeing the error
If you've updated your configuration and you're still hitting the 421 error:
1. Confirm your software is actually opening a new connection after every 5 emails and not just retrying the same connection.
2. Check whether you're also hitting the 120 authentication requests/minute limit by reviewing your send logs for authentication failures.
3. Reach out to our support team with your sending logs. We can help identify exactly where the limit is being hit.
Need more info?
Feel free to reach out to support@mailersend.com. A member of our support team will gladly assist you.
- Getting started: Sending your first email
-
Email
- Add and verify a sending domain
- How to merge multiple SPF records
- Start sending transactional emails
- SMTP relay
- Testing email sending with blackhole recipients
- Activity
- Analytics
- Bulk email sending
- Custom headers
- Custom unsubscribe headers
- Sending domains
- Domain tracking options
- Inbound routing
- Personalization in emails
- Sender identities
- Split Testing
- Surveys
- Tagging emails
- Templates
- How to configure SMTP connections correctly (421: Service not available error)
- How to enable Google Email Actions & Highlights
- How transactional emails work
- The difference between transactional emails and marketing emails
- SMS
- Developer tools
- Deliverability
-
Account, billing & add-ons
- Plans, features and limits
- Plan add-ons
- User management
- Change password
- Two-factor authentication
- Switch accounts
- How to whitelist IPs
- How to add a domain space to your account
- How to request a dedicated IP
- Account reputation statuses
- How to set a billing limit on your account
- How to change your payment method
- How to change or cancel your plan
- Delete account
- About MailerSend's refund and account policies
- VAT Collection for EU Customers
- VAT Collection for UK Customers
- GST Collection for Customers in India
- GST Collection for Customers in Canada
- VAT (IVA) Collection for Customers in Chile
- How to use the MailerSend iOS app
- File manager
- Invoicing update June, 2026
- Integrations
- Agency guides
- What causes the 421 error?
- How to fix it
- Option 1: Configure your software to open multiple connections
- PHPMailer
- WordPress + WP Mail SMTP
- Nodemailer (Node.js)
- smtplib (Python)
- Django (django.core.mail)
- Jakarta Mail/JavaMail (Java)
- Option 2: Implement proper send throttling
- Sending marketing emails
- Current SMTP limits
- What to do if you’re still seeing the error