jstedfast/MailKit · error · ServiceNotConnectedException
The Pop3Client is not connected.
Error message
The Pop3Client is not connected.
What it means
Pop3Client.CheckConnected is the guard invoked before nearly every network operation (GetMessageCount, Size, NoOp, language commands, etc.); it throws ServiceNotConnectedException when IsConnected is false. It means the client has never connected, or the connection was dropped/closed before the call.
Solutions
- Check client.IsConnected before operations and call ConnectAsync/AuthenticateAsync when false.
- Wrap operations in a reconnect helper: catch ServiceNotConnectedException, reconnect, retry once.
- Don't reuse stale client instances across long gaps; create and connect a fresh Pop3Client per unit of work (POP3 sessions are short-lived by design).
Example fix
// before
using var client = new Pop3Client();
await client.ConnectAsync(host, 995, true);
// ... later, connection dropped ...
int count = await client.GetMessageCountAsync(); // throws
// after
using var client = new Pop3Client();
async Task EnsureConnectedAsync()
{
if (!client.IsConnected)
{
await client.ConnectAsync(host, 995, true);
await client.AuthenticateAsync(user, pass);
}
}
await EnsureConnectedAsync();
int count = await client.GetMessageCountAsync(); Defensive patterns
Strategy: try-catch
Validate before calling
if (client == null || !client.IsConnected)
throw new InvalidOperationException("Pop3Client must be connected before use"); Try / catch
try { await client.GetMessageCountAsync(); }
catch (ServiceNotConnectedException) {
await client.ConnectAsync(host, 995, true);
await client.AuthenticateAsync(user, pass);
await client.GetMessageCountAsync();
} Prevention
- Check IsConnected before every operation or use a EnsureConnected helper
- Reconnect after any exception — MailKit disconnects the client on timeouts and protocol errors
- Create fresh Pop3Client sessions per unit of work; POP3 is not designed for long-lived connections
When it happens
Trigger: Calling any Pop3Client operation before ConnectAsync, after DisconnectAsync, after a timeout/protocol exception disconnected the client, or after the server dropped the connection.
Common situations: Reusing a client instance across a previous failed session; forgetting Connect in a code path; a prior TimeoutException/ImapProtocolException-style disconnect left the client dead and subsequent calls fail; wrong assumption that a client stays connected between application requests.
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
- The ImapClient is already connected.
- The ImapClient is not connected.
- The ImapClient is not authenticated.
- No credentials could be found for the POP3 server.
- The POP3 server does not support the STLS extension.
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/8639d1394d54bb68.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Pop3/Pop3Client.cs:250
get {
CheckDisposed ();
CheckConnected ();
CheckAuthenticated ();
return octets;
}
}
void CheckDisposed ()
{
if (disposed)
throw new ObjectDisposedException (nameof (Pop3Client));
}
void CheckConnected ()
{
if (!IsConnected)
throw new ServiceNotConnectedException ("The Pop3Client is not connected.");
}
void CheckAuthenticated ()
{
if (!IsAuthenticated)
throw new ServiceNotAuthenticatedException ("The Pop3Client has not been authenticated.");
}
bool ValidateRemoteCertificate (object? sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors)
{
var host = engine.Uri!.Host;
bool valid;
sslValidationInfo?.Dispose ();
sslValidationInfo = null;
if (ServerCertificateValidationCallback != null) {
valid = ServerCertificateValidationCallback (host, certificate, chain, sslPolicyErrors);View on GitHub (pinned to 9d3859a785)