jstedfast/MailKit · error · NotSupportedException

The IMAP server does not support the PARTIAL extension.

Error message

The IMAP server does not support the PARTIAL extension.

What it means

MailKit throws this NotSupportedException when a Search call supplies a PartialRange but the server neither advertises the PARTIAL capability (RFC 9394) nor CONTEXT=SEARCH with the SEARCH context (RFC 5267), the two specs that define partial search-result returns. The library refuses to send a partial range the server would reject or, worse, misinterpret.

Solutions

  1. Check client.Capabilities for ImapCapabilities.Partial (or Context with "SEARCH") before constructing a PartialRange.
  2. Fetch all matching UIDs with a plain Search and slice/paginate the result list in your application instead.
  3. Use folder.Fetch with ranges over the returned IDs to emulate partial retrieval.
  4. Upgrade or reconfigure the IMAP server to one supporting RFC 9394 PARTIAL or CONTEXT=SEARCH.

Example fix

// before
var results = folder.Search (SearchOptions.None, query, new PartialRange (0, 10));

// after
if (client.Capabilities.HasFlag (ImapCapabilities.Partial)) {
    var results = folder.Search (SearchOptions.None, query, new PartialRange (0, 10));
} else {
    var uids = folder.Search (query);
    var page = uids.Skip (0).Take (10).ToArray ();
}
Defensive patterns

Strategy: validation

Validate before calling

bool canPartial = client.Capabilities.HasFlag (ImapCapabilities.Partial) ||
    (client.Capabilities.HasFlag (ImapCapabilities.Context));
if (!canPartial)
    partialRange = null; // fall back to full search + client-side paging

Try / catch

try {
    results = folder.Search (SearchOptions.None, query, partialRange);
} catch (NotSupportedException) {
    var uids = folder.Search (query);
    results = PageClientSide (uids, partialRange);
}

Prevention

When it happens

Trigger: Calling folder.Search(SearchOptions.None, query, new PartialRange(0, 10)) or its async variant on a server lacking both ImapCapabilities.Partial and (Context + SupportedContexts containing "SEARCH").

Common situations: Paging through search results against older servers that predate RFC 9394 and don't implement CONTEXT=SEARCH; assuming the PARTIAL option is universally available; self-hosted IMAP servers with limited capability sets.

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


AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15). Data as JSON: /api/errors/8c6bcc56de74510e. Report an issue: GitHub.

Appendix: source

Thrown at MailKit/Net/Imap/ImapFolderSearch.cs:1052

			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 ");

			if ((Engine.Capabilities & ImapCapabilities.ESearch) != 0 || partialRange.HasValue) {
				command.Append ("RETURN (");

				if (options != SearchOptions.All && options != SearchOptions.None) {
					if ((options & SearchOptions.All) != 0)
						command.Append ("ALL ");
					if ((options & SearchOptions.Relevancy) != 0)

View on GitHub (pinned to 9d3859a785)