jstedfast/MailKit · error · InvalidOperationException
The SmtpClient is already connected.
Error message
The SmtpClient is already connected.
What it means
ValidateArguments/Connect throws InvalidOperationException when Connect is called on an SmtpClient that already has an active connection (IsConnected == true). A single SMTP session cannot be re-established in place; the existing connection must be closed first.
Solutions
- Call Disconnect(true) before calling Connect again, or create a new SmtpClient instance.
- Guard: if (!client.IsConnected) client.Connect(...).
- Use one SmtpClient per connection attempt/worker thread; the client is not thread-safe.
Example fix
// before
if (!client.IsConnected) {
client.Connect(host, 587, SecureSocketOptions.StartTls);
}
client.Disconnect(true);
client.Connect(host, 587, SecureSocketOptions.StartTls); // second Connect: fine, but pattern often misses Disconnect
// after
if (client.IsConnected)
client.Disconnect(true);
client.Connect(host, 587, SecureSocketOptions.StartTls); Defensive patterns
Strategy: validation
Validate before calling
if (client.IsConnected)
client.Disconnect(true);
client.Connect(host, port, options); Try / catch
try {
client.Connect(host, port, options);
} catch (InvalidOperationException) {
// already connected; reuse the existing session or Disconnect first
} Prevention
- Guard every Connect with an IsConnected check.
- Never share one SmtpClient across threads; it is not thread-safe.
- In retry loops, Disconnect before reconnecting.
- Dispose the client in a using/finally to guarantee clean state.
When it happens
Trigger: Calling Connect twice on the same client — e.g. retry logic that re-runs Connect after a Send failure on a still-live session, or a shared/singleton client connected once per request in a loop.
Common situations: Reconnect loops missing a Disconnect call; multiple threads sharing one SmtpClient instance and both attempting Connect; re-running an initialization routine on an already-started client.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- The SmtpClient must be connected before you can…
- Value cannot be null. (Parameter 'message')
- Value cannot be null. (Parameter 'response')
- The ImapClient is already connected.
- The ImapClient is not connected.
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/fe9403bd4fe55cf1.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Smtp/SmtpClient.cs:1417
OnConnected (host, port, options);
}
void ValidateArguments (string host, int port)
{
if (host == null)
throw new ArgumentNullException (nameof (host));
if (host.Length == 0)
throw new ArgumentException ("The host name cannot be empty.", nameof (host));
if (port < 0 || port > 65535)
throw new ArgumentOutOfRangeException (nameof (port));
CheckDisposed ();
if (IsConnected)
throw new InvalidOperationException ("The SmtpClient is already connected.");
}
/// <summary>
/// Establish a connection to the specified SMTP or SMTP/S server.
/// </summary>
/// <remarks>
/// <para>Establishes a connection to the specified SMTP or SMTP/S server.</para>
/// <para>If the <paramref name="port"/> has a value of <c>0</c>, then the
/// <paramref name="options"/> parameter is used to determine the default port to
/// connect to. The default port used with <see cref="SecureSocketOptions.SslOnConnect"/>
/// is <c>465</c>. All other values will use a default port of <c>25</c>.</para>
/// <para>If the <paramref name="options"/> has a value of
/// <see cref="SecureSocketOptions.Auto"/>, then the <paramref name="port"/> is used
/// to determine the default security options. If the <paramref name="port"/> has a value
/// of <c>465</c>, then the default options used will be
/// <see cref="SecureSocketOptions.SslOnConnect"/>. All other values will use
/// <see cref="SecureSocketOptions.StartTlsWhenAvailable"/>.</para>
/// <para>Once a connection is established, properties such asView on GitHub (pinned to 9d3859a785)