jstedfast/MailKit · error · NotSupportedException
The POP3 server does not support the STLS extension.
Error message
The POP3 server does not support the STLS extension.
What it means
In Pop3Client.PostConnectAsync, when SecureSocketOptions.StartTls is explicitly requested, MailKit checks the server's CAPA response for the StartTLS capability. If the server does not advertise STLS, it throws NotSupportedException because the requested TLS negotiation strategy cannot be honored.
Solutions
- Use SecureSocketOptions.SslOnConnect for implicit TLS on port 995, or Auto to let MailKit negotiate what the server supports.
- Verify the server actually supports STLS: connect and inspect client.Capabilities for the StartTLS flag.
- If TLS is genuinely unavailable, use SecureSocketOptions.None only on a trusted network (avoid sending credentials in plaintext).
Example fix
// before
await client.ConnectAsync("pop.example.com", 110, SecureSocketOptions.StartTls);
// after
// server only supports implicit TLS on 995
await client.ConnectAsync("pop.example.com", 995, SecureSocketOptions.SslOnConnect);
// or negotiate automatically:
await client.ConnectAsync("pop.example.com", 110, SecureSocketOptions.Auto); Defensive patterns
Strategy: validation
Validate before calling
// after connect, before relying on StartTls:
if ((client.Capabilities & Pop3Capabilities.StartTLS) == 0)
throw new InvalidOperationException("POP3 server does not support STLS; use implicit TLS on port 995"); Try / catch
try { await client.ConnectAsync(host, port, SecureSocketOptions.StartTls); }
catch (NotSupportedException) {
await client.ConnectAsync(host, 995, SecureSocketOptions.SslOnConnect);
} Prevention
- Use SecureSocketOptions.Auto or SslOnConnect instead of hard-coding StartTls
- Know your server's TLS mode: 995 = implicit SSL, 110 = plain or STLS if advertised
- Inspect client.Capabilities after connecting to confirm StartTLS support
When it happens
Trigger: client.ConnectAsync(host, port, SecureSocketOptions.StartTls) against a POP3 server that lacks the STLS capability (e.g. plain server without TLS support, or capability detection disabled).
Common situations: Configuring StartTls when the server only supports implicit TLS (port 995) or no TLS at all; self-hosted/minimal POP3 servers without STLS; misremembering the port (995 = implicit SSL, 110 = plain/STARTTLS).
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- The POP3 server does not support the STLS extension.
- The IMAP server does not support the STARTTLS extension.
- The IMAP server does not support the STARTTLS extension.
- The SMTP server does not support the STARTTLS extension.
- The LOGIN command is disabled.
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/743b15424b9a5907.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Pop3/AsyncPop3Client.cs:329
{
probed = ProbedCapabilities.None;
try {
ProtocolLogger.LogConnect (engine.Uri!);
} catch {
stream.Dispose ();
throw;
}
var pop3 = new Pop3Stream (stream, ProtocolLogger);
await engine.ConnectAsync (pop3, cancellationToken).ConfigureAwait (false);
try {
await engine.QueryCapabilitiesAsync (cancellationToken).ConfigureAwait (false);
if (options == SecureSocketOptions.StartTls && (engine.Capabilities & Pop3Capabilities.StartTLS) == 0)
throw new NotSupportedException ("The POP3 server does not support the STLS extension.");
if (starttls && (engine.Capabilities & Pop3Capabilities.StartTLS) != 0) {
await SendCommandAsync (cancellationToken, "STLS\r\n").ConfigureAwait (false);
try {
var tls = new ExtendedSslStream (stream, false, ValidateRemoteCertificate);
pop3.SetStream (tls);
await SslHandshakeAsync (tls, host, cancellationToken).ConfigureAwait (false);
} catch (Exception ex) {
throw SslHandshakeException.Create (ref sslValidationInfo, ex, true, "POP3", host, port, 995, 110);
}
engine.IsSecure = true;
// re-issue a CAPA command
await engine.QueryCapabilitiesAsync (cancellationToken).ConfigureAwait (false);
}View on GitHub (pinned to 9d3859a785)