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

  1. Call Disconnect(true) before calling Connect again, or create a new SmtpClient instance.
  2. Guard: if (!client.IsConnected) client.Connect(...).
  3. 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

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


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 as

View on GitHub (pinned to 9d3859a785)