jstedfast/MailKit · error · ServiceNotConnectedException
The ImapClient is not connected.
Error message
The ImapClient is not connected.
What it means
MailKit throws ServiceNotConnectedException from ImapFolder.CheckState whenever a folder operation is queued while the owning ImapClient has no active TCP/TLS connection to the IMAP server. CheckState is the gate for every folder command (open, close, create, rename, delete, subscribe), so this error means the command was issued before Connect/Authenticate or after the connection dropped.
Solutions
- Check ImapClient.IsConnected before issuing folder operations and reconnect (Connect + Authenticate) if false, then re-open the folder.
- Wrap the operation in try/catch for ServiceNotConnectedException and implement a reconnect-and-retry loop.
- If operations happen after long idle, keep the connection alive with ImapClient.NoOp() on a timer or reconnect per unit of work.
- Ensure Connect() and Authenticate() complete without exception before obtaining/using folder references.
- Create a fresh ImapClient per worker instead of sharing one across threads/outages.
Example fix
// before
var folder = client.GetFolder("INBOX");
folder.Open(FolderAccess.ReadWrite);
// after
if (!client.IsConnected)
{
client.Connect(host, port, SecureSocketOptions.Auto);
client.Authenticate(user, password);
}
var folder = client.GetFolder("INBOX");
folder.Open(FolderAccess.ReadWrite); Defensive patterns
Strategy: try-catch
Validate before calling
if (!client.IsConnected) { client.Connect(host, port, SecureSocketOptions.Auto); client.Authenticate(user, pass); } Type guard
bool CanUseFolder(ImapClient c) => c != null && c.IsConnected && c.IsAuthenticated;
Try / catch
try { folder.Open(FolderAccess.ReadWrite); } catch (ServiceNotConnectedException) { Reconnect(); folder.Open(FolderAccess.ReadWrite); } Prevention
- Check IsConnected before every folder operation batch.
- Reconnect + re-authenticate + re-open folder after any exception.
- Send NoOp periodically on idle connections to detect drops early.
- Avoid sharing one ImapClient across threads or long-lived background jobs.
When it happens
Trigger: Calling ImapFolder.Open/Close/Create/Rename/Delete/Subscribe (or any API that queues those commands) before ImapClient.Connect() succeeds, after ImapClient.Disconnect(), or after the underlying socket was closed by the server/network so Engine.IsConnected is false.
Common situations: Using a cached ImapFolder or ImapClient across a long idle period where the server dropped the connection (RFC auto-logout); forgetting Connect in a code path (e.g. a background job reusing a stale client); connecting on one thread and using folders after the connection was lost.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- The ImapClient is already connected.
- The ImapClient is not authenticated.
- The IMAP server has unexpectedly disconnected.
- Value cannot be null. (Parameter 'name')
- Value cannot be null. (Parameter 'rights')
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/50ba917a0effbe6a.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Imap/ImapFolder.cs:163
case FolderFeature.Annotations: return AnnotationAccess != AnnotationAccess.None;
case FolderFeature.Metadata: return (Engine.Capabilities & ImapCapabilities.Metadata) != 0;
case FolderFeature.ModSequences: return supportsModSeq;
case FolderFeature.QuickResync: return Engine.QResyncEnabled;
case FolderFeature.Quotas: return (Engine.Capabilities & ImapCapabilities.Quota) != 0;
case FolderFeature.Sorting: return (Engine.Capabilities & ImapCapabilities.Sort) != 0;
case FolderFeature.Threading: return (Engine.Capabilities & ImapCapabilities.Thread) != 0;
case FolderFeature.UTF8: return Engine.UTF8Enabled;
default: return false;
}
}
void CheckState (bool open, bool rw)
{
if (Engine.IsDisposed)
throw new ObjectDisposedException (nameof (ImapClient));
if (!Engine.IsConnected)
throw new ServiceNotConnectedException ("The ImapClient is not connected.");
if (Engine.State < ImapEngineState.Authenticated)
throw new ServiceNotAuthenticatedException ("The ImapClient is not authenticated.");
if (open) {
var access = rw ? FolderAccess.ReadWrite : FolderAccess.ReadOnly;
if (!IsOpen || Access < access)
throw new FolderNotOpenException (FullName, access);
}
}
void CheckAllowIndexes ()
{
// Indexes ("Message Sequence Numbers" or MSNs in the RFCs) and * are not stable while MessageNew/MessageExpunge is registered for SELECTED and therefore should not be used
// https://tools.ietf.org/html/rfc5465#section-5.2
if (Engine.NotifySelectedNewExpunge)
throw new InvalidOperationException ("Indexes and '*' cannot be used while MessageNew/MessageExpunge is registered with NOTIFY for SELECTED.");View on GitHub (pinned to 9d3859a785)