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

  1. Catch SmtpProtocolException and reconnect with a fresh SmtpClient (MailKit marks IsConnected=false)
  2. Enable client.Timeout/keepalives and resend messages with backoff for transient disconnects
  3. 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

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


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)