jstedfast/MailKit · error · ServiceNotConnectedException
The SmtpClient must be connected before you can…
Error message
The SmtpClient must be connected before you can authenticate.
What it means
MailKit's SmtpClient.Authenticate (SASL mechanism overload) throws ServiceNotConnectedException because IsConnected is false when Authenticate is called. The client requires a completed Connect (and typically EHLO negotiation) before any AUTH command can be sent. This is a strict state-machine guard: authentication without a live socket is meaningless.
Solutions
- Call SmtpClient.Connect(host, port, SecureSocketOptions) and check it succeeds before calling Authenticate.
- Wrap the whole connect/authenticate/send sequence in try-catch so a failed Connect aborts the flow instead of falling through to Authenticate.
- If reusing the client, check client.IsConnected (and !client.IsDisposed) before Authenticate, or create a fresh SmtpClient instance.
Example fix
// before
var client = new SmtpClient();
client.Authenticate("user", "pass"); // throws ServiceNotConnectedException
// after
var client = new SmtpClient();
client.Connect("smtp.example.com", 465, SecureSocketOptions.SslOnConnect);
client.Authenticate("user", "pass"); Defensive patterns
Strategy: try-catch
Validate before calling
if (client == null || client.IsDisposed || !client.IsConnected)
throw new InvalidOperationException("SmtpClient must be connected before authenticating."); Try / catch
try {
client.Authenticate(mechanism);
} catch (ServiceNotConnectedException) {
// reconnect then retry authenticate
client.Connect(host, port, SecureSocketOptions.StartTls);
client.Authenticate(mechanism);
} Prevention
- Always call Connect immediately before Authenticate in the same method.
- Never swallow exceptions from Connect.
- Assert client.IsConnected in debug builds before authenticating.
When it happens
Trigger: Calling SmtpClient.Authenticate(string mechanismName, string user, string password) or Authenticate(SaslMechanism, ...) without calling Connect first, or after the connection has been dropped by the server or network.
Common situations: Forgetting the Connect call (or commenting it out in refactored code); Connect succeeding but the server dropping the connection before Authenticate; reusing a client instance after Disconnect/Dispose; async/await code paths where an exception during Connect is swallowed and execution continues to Authenticate.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- The ImapClient is not authenticated.
- The SmtpClient is already connected.
- message
- Value cannot be null. (Parameter 'encoding')
- Value cannot be null. (Parameter 'userName')
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/33c73709f1ea0419.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Smtp/SmtpClient.cs:999
// Try sending HELO instead...
response = SendEhlo (connecting, "HELO", cancellationToken);
if (response.StatusCode != SmtpStatusCode.Ok)
throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);
} else {
UpdateCapabilities (response);
}
}
void ValidateArguments (SaslMechanism mechanism)
{
if (mechanism == null)
throw new ArgumentNullException (nameof (mechanism));
CheckDisposed ();
if (!IsConnected)
throw new ServiceNotConnectedException ("The SmtpClient must be connected before you can authenticate.");
if (IsAuthenticated)
throw new InvalidOperationException ("The SmtpClient is already authenticated.");
if ((capabilities & SmtpCapabilities.Authentication) == 0)
throw new NotSupportedException ("The SMTP server does not support authentication.");
mechanism.ChannelBindingContext = Stream.Stream as IChannelBindingContext;
mechanism.Uri = new Uri ($"smtp://{uri.Host}");
}
/// <summary>
/// Authenticate using the specified SASL mechanism.
/// </summary>
/// <remarks>
/// <para>Authenticates using the specified SASL mechanism.</para>
/// <para>For a list of available SASL authentication mechanisms supported by the server,
/// check the <see cref="AuthenticationMechanisms"/> property after the service has beenView on GitHub (pinned to 9d3859a785)