jstedfast/MailKit · error · InvalidOperationException

The ImapClient is already connected.

Error message

The ImapClient is already connected.

What it means

ImapClient throws this InvalidOperationException when Connect is called while the client already has an active connection (IsConnected == true). MailKit guards the connection state machine so a second connection attempt cannot corrupt the existing session.

Solutions

  1. Check client.IsConnected before calling Connect and skip if already connected
  2. Call client.Disconnect(true) before reconnecting the same instance
  3. Create a new ImapClient instance per connection instead of reusing one
  4. Serialize connect logic so only one path ever calls Connect

Example fix

// before
client.Connect(host, port, SecureSocketOptions.Auto);
// after
if (!client.IsConnected)
    client.Connect(host, port, SecureSocketOptions.Auto);
Defensive patterns

Strategy: validation

Validate before calling

if (client.IsConnected) return; // skip redundant connect
client.Connect(host, port, SecureSocketOptions.Auto);

Try / catch

try { client.Connect(host, port, options); }
catch (InvalidOperationException) { /* already connected - treat as success */ }

Prevention

When it happens

Trigger: Calling any Connect/ConnectSocket overload while IsConnected is true; retrying connect logic in a loop without first checking or disconnecting the prior session.

Common situations: Auto-reconnect code that forgot a Disconnect call after a network blip; app restart of a connect routine reusing a client instance that stayed connected; sharing one ImapClient across threads that each try to connect.

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/579ca4613d0ab582. Report an issue: GitHub.

Appendix: source

Thrown at MailKit/Net/Imap/ImapClient.cs:1444

				break;
			}
		}

		void CheckCanConnect (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 ImapClient is already connected.");
		}

		void SslHandshake (SslStream ssl, string host, CancellationToken cancellationToken)
		{
#if NET5_0_OR_GREATER
			ssl.AuthenticateAsClient (GetSslClientAuthenticationOptions (host, ValidateRemoteCertificate));
#else
			ssl.AuthenticateAsClient (host, ClientCertificates, SslProtocols, CheckCertificateRevocation);
#endif
		}

		void PostConnect (Stream stream, string host, int port, SecureSocketOptions options, bool starttls, CancellationToken cancellationToken)
		{
			try {
				ProtocolLogger.LogConnect (engine.Uri!);
			} catch {
				stream.Dispose ();
				throw;

View on GitHub (pinned to 9d3859a785)