jstedfast/MailKit · error · InvalidOperationException

The Pop3Client is already connected.

Error message

The Pop3Client is already connected.

What it means

CheckCanConnect throws InvalidOperationException when Connect is called on a Pop3Client that already has an active connection (IsConnected is true). A Pop3Client instance manages exactly one POP3 session at a time, so connecting twice without disconnecting is refused. To connect elsewhere you must Disconnect (or dispose and create a new client) first.

Solutions

  1. Guard the call: only Connect when !client.IsConnected.
  2. Call Disconnect(quit: true, cancellationToken) before connecting to a new host/port.
  3. If a second concurrent session is needed, create a new Pop3Client instance instead of reusing the connected one.
  4. For reconnect-after-failure, check IsConnected and only reconnect when the previous session actually dropped.

Example fix

// before
client.Connect("pop.example.com", 995, SecureSocketOptions.SslOnConnect, ct);
// ... elsewhere
client.Connect("pop.other.com", 995, SecureSocketOptions.SslOnConnect, ct); // throws

// after
if (!client.IsConnected)
    client.Connect("pop.other.com", 995, SecureSocketOptions.SslOnConnect, ct);
Defensive patterns

Strategy: validation

Validate before calling

if (!client.IsConnected)
    client.Connect(host, port, SecureSocketOptions.SslOnConnect, cancellationToken);
// else: reuse the existing session

Try / catch

try {
    client.Connect(host, port, SecureSocketOptions.SslOnConnect, ct);
} catch (InvalidOperationException) {
    // already connected; reuse session or Disconnect first if a new target is required
}

Prevention

When it happens

Trigger: Calling Connect() twice on the same Pop3Client instance without Disconnect(); a code path that re-connects on a timer/retry while the first session is still alive; reusing a singleton client for a different server while connected to the first.

Common situations: Auto-reconnect wrappers that forgot to check IsConnected; DI singleton Pop3Client shared across services that each call Connect; switching server/port settings at runtime without disconnecting first.

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/7883b9de8d5d9bf4. Report an issue: GitHub.

Appendix: source

Thrown at MailKit/Net/Pop3/Pop3Client.cs:1101

				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 Pop3Client 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)
		{
			probed = ProbedCapabilities.None;

			try {
				ProtocolLogger.LogConnect (engine.Uri!);
			} catch {

View on GitHub (pinned to 9d3859a785)