jstedfast/MailKit · error · NotSupportedException
The IMAP server does not support the ESEARCH extension.
Error message
The IMAP server does not support the ESEARCH extension.
What it means
MailKit throws this NotSupportedException from ImapFolder.QueueSearchCommand when a Search call passes SearchOptions other than None but the server never advertised the ESEARCH capability (RFC 4731) during connection. The ESEARCH extension is what allows servers to return counts, min/max ids, or save results instead of plain sequence numbers. Without it, only a plain SEARCH with no result options can be honored.
Solutions
- Check ImapClient.Capabilities.HasFlag(ImapCapabilities.ESearch) before passing non-None options; fall back to SearchOptions.None and post-process results client-side.
- Call Search(SearchOptions.None, query) and compute Count/Final yourself from the returned unique IDs.
- Switch to an IMAP server that supports ESEARCH (most modern servers: Dovecot, Cyrus, Exchange 2016+).
- Wrap the Search call in try/catch for NotSupportedException and retry with options = SearchOptions.None.
Example fix
// before
var results = folder.Search (SearchOptions.Count, query);
// after
var options = client.Capabilities.HasFlag (ImapCapabilities.ESearch)
? SearchOptions.Count
: SearchOptions.None;
var results = folder.Search (options, query); Defensive patterns
Strategy: validation
Validate before calling
bool canUseEsearch = client.Capabilities.HasFlag (ImapCapabilities.ESearch);
if (!canUseEsearch && options != SearchOptions.None)
options = SearchOptions.None; // degrade before calling folder.Search Try / catch
try {
results = folder.Search (options, query);
} catch (NotSupportedException) {
results = folder.Search (SearchOptions.None, query); // recompute client-side
} Prevention
- Log ImapClient.Capabilities after connecting and assert required extensions (ESEARCH) in startup checks.
- Feature-detect capabilities once and store a capabilities profile for the session.
- Never hardcode non-None SearchOptions in shared code paths without a capability check.
When it happens
Trigger: Calling folder.Search(SearchOptions.Final | SearchOptions.Count, query, ...) or the async variants with options != SearchOptions.None on a server whose CAPABILITY response lacks ESEARCH. Note the check is skipped entirely when options == SearchOptions.None.
Common situations: Connecting to old or minimal IMAP servers (embedded mail servers, some proxies) that never implemented RFC 4731; code that always passes SearchOptions.Count out of habit; a server downgrade or new host where ESEARCH is not advertised.
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 IMAP server does not support the PARTIAL extension.
- The IMAP server does not support the SORT extension.
- The IMAP server does not support the QRESYNC extension.
- The IMAP server does not support the METADATA extension.
- The IMAP server does not support the QUOTA extension.
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/26edc325bfd63d1b.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Imap/ImapFolderSearch.cs:1045
/// </exception>
public virtual async Task<SearchResults> SearchAsync (string query, CancellationToken cancellationToken = default)
{
var ic = QueueSearchCommand (query, cancellationToken);
await Engine.RunAsync (ic).ConfigureAwait (false);
return ProcessSearchResponse (ic);
}
ImapCommand QueueSearchCommand (SearchOptions options, SearchQuery query, PartialRange? partialRange, CancellationToken cancellationToken, out string? charset)
{
if (query == null)
throw new ArgumentNullException (nameof (query));
CheckState (true, false);
if (options != SearchOptions.None && (Engine.Capabilities & ImapCapabilities.ESearch) == 0)
throw new NotSupportedException ("The IMAP server does not support the ESEARCH extension.");
if (partialRange.HasValue) {
// Note: RFC 9394 advertises the "PARTIAL" capability while RFC 5267 defines the same PARTIAL
// search return option under the "CONTEXT=SEARCH" capability.
if ((Engine.Capabilities & ImapCapabilities.Partial) == 0 &&
((Engine.Capabilities & ImapCapabilities.Context) == 0 || !Engine.SupportedContexts.Contains ("SEARCH")))
throw new NotSupportedException ("The IMAP server does not support the PARTIAL extension.");
// Note: Negative partial ranges were introduced in RFC 9394 and are not defined by RFC 5267.
if (partialRange.Value.First < 0 && (Engine.Capabilities & ImapCapabilities.Partial) == 0)
throw new NotSupportedException ("The IMAP server does not support negative partial ranges.");
}
var args = new List<object> ();
var optimized = query.Optimize (new ImapSearchQueryOptimizer ());
var expr = BuildQueryExpression (optimized, args, out charset);
var command = new StringBuilder ("UID SEARCH ");
View on GitHub (pinned to 9d3859a785)