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

  1. Call SmtpClient.Connect(host, port, SecureSocketOptions) and check it succeeds before calling Authenticate.
  2. Wrap the whole connect/authenticate/send sequence in try-catch so a failed Connect aborts the flow instead of falling through to Authenticate.
  3. 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

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

Related errors


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 been

View on GitHub (pinned to 9d3859a785)