{"record":{"id":"579ca4613d0ab582","repo":"jstedfast/MailKit","slug":"the-imapclient-is-already-connected","errorCode":null,"errorMessage":"The ImapClient is already connected.","messagePattern":"The ImapClient is already connected\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"MailKit/Net/Imap/ImapClient.cs","lineNumber":1444,"sourceCode":"\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tvoid CheckCanConnect (string host, int port)\n\t\t{\n\t\t\tif (host == null)\n\t\t\t\tthrow new ArgumentNullException (nameof (host));\n\n\t\t\tif (host.Length == 0)\n\t\t\t\tthrow new ArgumentException (\"The host name cannot be empty.\", nameof (host));\n\n\t\t\tif (port < 0 || port > 65535)\n\t\t\t\tthrow new ArgumentOutOfRangeException (nameof (port));\n\n\t\t\tCheckDisposed ();\n\n\t\t\tif (IsConnected)\n\t\t\t\tthrow new InvalidOperationException (\"The ImapClient is already connected.\");\n\t\t}\n\n\t\tvoid SslHandshake (SslStream ssl, string host, CancellationToken cancellationToken)\n\t\t{\n#if NET5_0_OR_GREATER\n\t\t\tssl.AuthenticateAsClient (GetSslClientAuthenticationOptions (host, ValidateRemoteCertificate));\n#else\n\t\t\tssl.AuthenticateAsClient (host, ClientCertificates, SslProtocols, CheckCertificateRevocation);\n#endif\n\t\t}\n\n\t\tvoid PostConnect (Stream stream, string host, int port, SecureSocketOptions options, bool starttls, CancellationToken cancellationToken)\n\t\t{\n\t\t\ttry {\n\t\t\t\tProtocolLogger.LogConnect (engine.Uri!);\n\t\t\t} catch {\n\t\t\t\tstream.Dispose ();\n\t\t\t\tthrow;","sourceCodeStart":1426,"sourceCodeEnd":1462,"githubUrl":"https://github.com/jstedfast/MailKit/blob/9d3859a7855e3e17582c07fd01972b8e262bf176/MailKit/Net/Imap/ImapClient.cs#L1426-L1462","documentation":"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.","triggerScenarios":"Calling any Connect/ConnectSocket overload while IsConnected is true; retrying connect logic in a loop without first checking or disconnecting the prior session.","commonSituations":"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.","solutions":["Check client.IsConnected before calling Connect and skip if already connected","Call client.Disconnect(true) before reconnecting the same instance","Create a new ImapClient instance per connection instead of reusing one","Serialize connect logic so only one path ever calls Connect"],"exampleFix":"// before\nclient.Connect(host, port, SecureSocketOptions.Auto);\n// after\nif (!client.IsConnected)\n    client.Connect(host, port, SecureSocketOptions.Auto);","handlingStrategy":"validation","validationCode":"if (client.IsConnected) return; // skip redundant connect\nclient.Connect(host, port, SecureSocketOptions.Auto);","typeGuard":null,"tryCatchPattern":"try { client.Connect(host, port, options); }\ncatch (InvalidOperationException) { /* already connected - treat as success */ }","preventionTips":["Always check IsConnected before Connect","Call Disconnect(true) in a finally block when done","Use one owner/thread per ImapClient instance"],"tags":["imap","connection-state","mailkit"],"backgroundTag":"invalid-state-transition","analyzedSha":"9d3859a7855e3e17582c07fd01972b8e262bf176","analyzedAt":"2026-09-15T15:46:11.592Z","contentChangedAt":"2026-09-15T15:46:11.592Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}