jstedfast/MailKit · error · ImapProtocolException
format, args
Error message
format, args
What it means
ImapEngine.AssertToken verifies that the token parsed from the IMAP server's response has the expected ImapTokenType; when it does not, it throws an ImapProtocolException (via UnexpectedToken) with UnexpectedToken set, carrying a formatted message. This means the server sent a response that violates the IMAP protocol grammar at the point being parsed — the library cannot interpret the reply.
Solutions
- Verify you are connecting to a real IMAP server on the correct port (993/143) and that TLS settings are correct.
- Capture the raw protocol trace (client can be hooked via ImapClient's tracing / ProtocolLogger) to see the malformed server response.
- Check for known server quirks (e.g. mail.ru formatting integers as 9.3736e+06); update MailKit, which carries workarounds for many broken servers.
- Retry the command if the failure is transient (truncated/garbled response), or reconnect and resume.
Example fix
// before
client.Connect ("mail.example.com", 587, SecureSocketOptions.None); // wrong service/port -> garbage tokens
client.Authenticate ("user", "pass");
// after
client.Connect ("imap.example.com", 993, SecureSocketOptions.SslOnConnect);
client.Authenticate ("user", "pass"); Defensive patterns
Strategy: try-catch
Try / catch
try {
client.Connect (host, port, SecureSocketOptions.SslOnConnect);
} catch (ImapProtocolException ex) when (ex.UnexpectedToken) {
logger.LogError ("Malformed IMAP response during connect: {0}", ex.Message);
} Prevention
- Connect only to verified IMAP endpoints/ports; wrong ports yield garbage tokens.
- Enable a ProtocolLogger in development to capture offending server lines early.
- Keep MailKit updated for workarounds against known broken servers.
- Prefer explicit SecureSocketOptions over None/Auto to avoid protocol confusion.
When it happens
Trigger: Any of the callers (ParseNumber, ParseNumber64, ParseUidSet, Connect, ConnectAsync, UpdateCapabilities) encountering a token of the wrong type while parsing a server response — e.g. Connect/UpdateCapabilities expecting an untagged CAPABILITY response with an atom token but receiving something else, or ParseUidSet hitting a non-atom token where a UID set was expected.
Common situations: Talking to a broken or non-compliant IMAP server (proxies, gateways, vendor-specific servers) whose responses deviate from RFC 3501; MITM/firewall injecting HTML error pages; connecting to a non-IMAP port; protocol downgrade or truncated responses.
Related errors
- Value cannot be null. (Parameter 'name')
- Value cannot be null. (Parameter 'rights')
- Value cannot be null. (Parameter 'array')
- Specified argument was out of range of valid values…
- Specified argument was out of range of valid values…
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/1187efac51eb18cc.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Imap/ImapEngine.cs:612
if (args[i] is ImapToken token) {
switch (token.Type) {
case ImapTokenType.Atom: args[i] = string.Format ("Unexpected atom token: {0}", token); break;
case ImapTokenType.Flag: args[i] = string.Format ("Unexpected flag token: {0}", token); break;
case ImapTokenType.QString: args[i] = string.Format ("Unexpected qstring token: {0}", token); break;
case ImapTokenType.Literal: args[i] = string.Format ("Unexpected literal token: {0}", token); break;
default: args[i] = string.Format ("Unexpected token: {0}", token); break;
}
break;
}
}
return new ImapProtocolException (string.Format (CultureInfo.InvariantCulture, format, args)) { UnexpectedToken = true };
}
internal static void AssertToken (ImapToken token, ImapTokenType type, string format, params object[] args)
{
if (token.Type != type)
throw UnexpectedToken (format, args);
}
internal static void AssertToken (ImapToken token, ImapTokenType type1, ImapTokenType type2, string format, params object[] args)
{
if (token.Type != type1 && token.Type != type2)
throw UnexpectedToken (format, args);
}
internal static uint ParseNumber (ImapToken token, bool nonZero, string format, params object[] args)
{
AssertToken (token, ImapTokenType.Atom, format, args);
// Note: Broken IMAP servers such as mail.ru sometimes incorrectly format integers as numbers with decimals and exponents. (e.g. 9.3736e+06)
// See https://github.com/jstedfast/MailKit/issues/1838 and https://github.com/jstedfast/MailKit/issues/1840 for details.
if (!uint.TryParse ((string) token.Value, NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out var value) || (nonZero && value == 0))
throw UnexpectedToken (format, args);
return value;View on GitHub (pinned to 9d3859a785)