jstedfast/MailKit · error · ServiceNotConnectedException
The SmtpClient is not connected.
Error message
The SmtpClient is not connected.
What it means
SmtpClient.NoOp() sends the SMTP NOOP command, which is only valid on an established session. MailKit checks IsConnected and throws ServiceNotConnectedException when the client has not completed a successful Connect (or the connection has since been dropped).
Solutions
- Check client.IsConnected before calling NoOp and reconnect if false
- Call Connect() (and Authenticate if needed) before any protocol operation
- Wrap keep-alive logic so a dropped connection triggers a fresh Connect instead of NoOp
- Enable protocol logging (new ProtocolLogger(Console.OpenStandardError())) to see when the server closes the connection
Example fix
// before
client.NoOp(); // throws if disconnected
// after
if (!client.IsConnected) {
client.Connect("smtp.example.com", 465, SecureSocketOptions.SslOnConnect);
client.Authenticate("user", "pass");
}
client.NoOp(); Defensive patterns
Strategy: validation
Validate before calling
if (!client.IsConnected) {
client.Connect(host, port, SecureSocketOptions.StartTls);
}
if (client.IsAuthenticated == false && client.RequiresAuthentication)
client.Authenticate(user, pass);
client.NoOp(); Type guard
bool CanUseClient(SmtpClient c) => c != null && !c.IsDisposed && c.IsConnected;
Try / catch
try { client.NoOp(); }
catch (ServiceNotConnectedException) {
client.Connect(host, port, SecureSocketOptions.StartTls);
client.NoOp();
} Prevention
- Gate every protocol call behind IsConnected checks
- Reconnect after any exception that may have dropped the connection
- Ping/keep-alive at intervals shorter than the server's idle timeout
- Avoid caching SmtpClient instances across long-lived requests without revalidating state
When it happens
Trigger: Calling NoOp() before ever calling Connect(), after calling Disconnect(), or after the server closed the socket (timeout, server restart, network drop).
Common situations: Keep-alive loops that call NoOp on a client whose idle connection was reaped by the server; reusing a cached SmtpClient instance across requests; forgetting that an exception in a prior operation disconnected the client.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- The SmtpClient is not connected.
- The SmtpClient must be connected before you can send…
- The SmtpClient must be connected before you can send…
- The SmtpClient must be connected before you can…
- The SmtpClient is already connected.
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/5a63d49263e7b849.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Smtp/SmtpClient.cs:1789
/// </exception>
/// <exception cref="System.OperationCanceledException">
/// The operation was canceled.
/// </exception>
/// <exception cref="System.IO.IOException">
/// An I/O error occurred.
/// </exception>
/// <exception cref="SmtpCommandException">
/// The SMTP command failed.
/// </exception>
/// <exception cref="SmtpProtocolException">
/// An SMTP protocol error occurred.
/// </exception>
public override void NoOp (CancellationToken cancellationToken = default)
{
CheckDisposed ();
if (!IsConnected)
throw new ServiceNotConnectedException ("The SmtpClient is not connected.");
var response = SendCommandInternal ("NOOP\r\n", cancellationToken);
if (response.StatusCode != SmtpStatusCode.Ok)
throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);
}
void Disconnect (string? host, int port, SecureSocketOptions options, bool requested)
{
// Note: if the uri is null, then the user manually disconnected already.
if (uri != null)
RecordClientDisconnected (null);
capabilities = SmtpCapabilities.None;
authenticated = false;
connected = false;
secure = false;
queued.Clear ();View on GitHub (pinned to 9d3859a785)