{"record":{"id":"3c56474280196b70","repo":"jstedfast/MailKit","slug":"the-smtp-server-has-unexpectedly-disconnected","errorCode":null,"errorMessage":"The SMTP server has unexpectedly disconnected.","messagePattern":"The SMTP server has unexpectedly disconnected\\.","errorType":"exception","errorClass":"SmtpProtocolException","httpStatus":null,"severity":"error","filePath":"MailKit/Net/Smtp/SmtpStream.cs","lineNumber":255,"sourceCode":"\n\t\t\ttry {\n\t\t\t\tvar network = Stream as NetworkStream;\n\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested ();\n\n\t\t\t\tnetwork?.Poll (SelectMode.SelectRead, cancellationToken);\n\t\t\t\tint nread = Stream.Read (input, offset, count);\n\n\t\t\t\tif (nread > 0) {\n\t\t\t\t\tlogger.LogServer (input, offset, nread);\n\t\t\t\t\tinputEnd += nread;\n\n\t\t\t\t\t// Optimization hack used by ReadResponse\n\t\t\t\t\tinput[inputEnd] = (byte) '\\n';\n\t\t\t\t} else if (lastResponse is not null) {\n\t\t\t\t\tthrow new SmtpProtocolException ($\"The SMTP server has unexpectedly disconnected: {lastResponse}\");\n\t\t\t\t} else {\n\t\t\t\t\tthrow new SmtpProtocolException (\"The SMTP server has unexpectedly disconnected.\");\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tIsConnected = false;\n\t\t\t\tthrow;\n\t\t\t}\n\n\t\t\treturn inputEnd - inputIndex;\n\t\t}\n\n\t\tasync Task<int> ReadAheadAsync (CancellationToken cancellationToken)\n\t\t{\n\t\t\tAlignReadAheadBuffer (out int offset, out int count);\n\n\t\t\ttry {\n\t\t\t\tcancellationToken.ThrowIfCancellationRequested ();\n\n\t\t\t\tint nread = await Stream.ReadAsync (input, offset, count, cancellationToken).ConfigureAwait (false);\n","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/jstedfast/MailKit/blob/9d3859a7855e3e17582c07fd01972b8e262bf176/MailKit/Net/Smtp/SmtpStream.cs#L237-L273","documentation":"Same family as [493]: ReadAhead throws SmtpProtocolException 'The SMTP server has unexpectedly disconnected.' when the server closes the connection with no partial response buffered (lastResponse is null). The connection reached EOF before any reply data arrived.","triggerScenarios":"Server closes the socket before completing a response; connection dropped between sending a command and reading the reply; server process killed mid-exchange.","commonSituations":"Idle connection reaped by server or NAT/firewall; server restarted; sending on a connection the server already closed after a previous 421.","solutions":["Reconnect and retry the operation; the SmtpClient marks the session dead (IsConnected=false)","Use fresh connections per burst of work or implement keepalive/NOOP pinging","Check server and firewall timeout settings versus your connection idle time"],"exampleFix":"// before\nclient.Send(message);\n// after\nif (!client.IsConnected) { client.Connect(host, port, useSsl); client.Authenticate(user, pass); }\ntry { client.Send(message); }\ncatch (SmtpProtocolException) { /* reconnect and retry */ }","handlingStrategy":"retry","validationCode":"if (!client.IsConnected) { client.Connect(host, port, useSsl); client.Authenticate(user, pass); }","typeGuard":null,"tryCatchPattern":"try { client.Send(message); }\ncatch (SmtpProtocolException) { client.Dispose(); client = CreateConnectedClient(); /* retry */ }","preventionTips":["Do not reuse long-idle connections; reconnect per batch","Send QUIT/dispose cleanly so servers don't blacklist the endpoint","Monitor server logs for idle-timeout kills"],"tags":["smtp","mailkit","network","disconnection"],"backgroundTag":"broken-pipe","analyzedSha":"9d3859a7855e3e17582c07fd01972b8e262bf176","analyzedAt":"2026-09-15T15:46:11.592Z","contentChangedAt":"2026-09-15T15:46:11.592Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}