jstedfast/MailKit · error · SmtpProtocolException
The SMTP server has unexpectedly disconnected
Error message
The SMTP server has unexpectedly disconnected: {lastResponse} What it means
SmtpStream.ReadAhead throws SmtpProtocolException when the socket read returns 0 bytes (EOF) mid-protocol while a partial response (lastResponse) was already buffered. The exception message includes that partial response to aid diagnosis. It means the server terminated the TCP connection without completing the SMTP exchange.
Solutions
- Catch SmtpProtocolException and reconnect with a fresh SmtpClient (MailKit marks IsConnected=false)
- Enable client.Timeout/keepalives and resend messages with backoff for transient disconnects
- Check server logs for why it dropped the connection (timeouts, limits, TLS issues)
Example fix
// before
await client.SendAsync(message); // throws on server disconnect
// after
for (int attempt = 0; attempt < 3; attempt++) {
try { await client.SendAsync(message); break; }
catch (SmtpProtocolException) {
await client.ConnectAsync(host, port, useSsl);
await client.AuthenticateAsync(user, pass);
}
} Defensive patterns
Strategy: retry
Validate before calling
if (!client.IsConnected) { client.Connect(host, port, useSsl); client.Authenticate(user, pass); } Try / catch
try { client.Send(message); }
catch (SmtpProtocolException ex) {
logger.LogWarning(ex, "Server dropped connection: {0}", ex.Message);
// reconnect and retry with backoff
} Prevention
- Keep idle time below server/firewall timeouts
- Reconnect after any SmtpProtocolException — the session is unrecoverable
- Retry with exponential backoff; transient disconnects are common
When it happens
Trigger: Server closes the socket after sending a partial reply line; connection reset between the greeting/response lines; idle timeout on the server side during a multi-line read.
Common situations: Server-side idle timeouts killing long-lived connections; firewalls/LBs dropping connections; SMTP server crash or restart mid-session; sending commands too fast after a 421 transient failure.
Related errors
- The SMTP server has unexpectedly disconnected.
- The POP3 server has unexpectedly disconnected.
- Specified argument was out of the range of valid values…
- Value cannot be null. (Parameter 'message')
- Value cannot be null. (Parameter 'response')
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/7783f618c42599e7.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Smtp/SmtpStream.cs:253
{
AlignReadAheadBuffer (out int offset, out int count);
try {
var network = Stream as NetworkStream;
cancellationToken.ThrowIfCancellationRequested ();
network?.Poll (SelectMode.SelectRead, cancellationToken);
int nread = Stream.Read (input, offset, count);
if (nread > 0) {
logger.LogServer (input, offset, nread);
inputEnd += nread;
// Optimization hack used by ReadResponse
input[inputEnd] = (byte) '\n';
} else if (lastResponse is not null) {
throw new SmtpProtocolException ($"The SMTP server has unexpectedly disconnected: {lastResponse}");
} else {
throw new SmtpProtocolException ("The SMTP server has unexpectedly disconnected.");
}
} catch {
IsConnected = false;
throw;
}
return inputEnd - inputIndex;
}
async Task<int> ReadAheadAsync (CancellationToken cancellationToken)
{
AlignReadAheadBuffer (out int offset, out int count);
try {
cancellationToken.ThrowIfCancellationRequested ();
View on GitHub (pinned to 9d3859a785)