jstedfast/MailKit · error · NotSupportedException
The set of unique identifiers is too large to fetch with a…
Error message
The set of unique identifiers is too large to fetch with a partial range.
What it means
CreateFetchCommands throws this NotSupportedException when a PARTIAL fetch would require more than one FETCH command. The PARTIAL modifier applies per-command, so MailKit would have to split large UID sets into multiple commands, and splitting would restart the partial offset for each command, changing the request semantics. Rather than return wrong data, it throws.
Solutions
- Batch the UID list so each call stays within the single-command limit (fetch in chunks of ~1000 or fewer UIDs)
- Fetch by sequence-number range or use a single UID range (e.g. new UniqueIdRange(...)) that maps to one command
- Drop PartialRange if you don't need partial semantics, allowing the normal multi-command splitting
Example fix
// before
var summaries = folder.Fetch(allUids, requestWithPartialRange); // allUids.Count = 5000
// after
foreach (var chunk in Chunk(allUids, 1000))
folder.Fetch(chunk, requestWithPartialRange); // each within a single FETCH command Defensive patterns
Strategy: validation
Validate before calling
const int MaxUidsPerPartialFetch = 1000;
if (request.PartialRange.HasValue && uids.Count > MaxUidsPerPartialFetch)
throw new InvalidOperationException("Chunk the UID set before a partial fetch."); Try / catch
try {
summaries = folder.Fetch(uids, request);
} catch (NotSupportedException ex) when (ex.Message.Contains("partial range")) {
foreach (var chunk in Chunk(uids, 1000))
foreach (var s in folder.Fetch(chunk, request))
yield return s;
} Prevention
- Never combine large UID sets with PartialRange; chunk to ~1000 UIDs per call
- Remember PARTIAL applies per FETCH command, so splitting changes offsets
- Use a single UID range instead of large exact UID sets when resuming with partial fetch
When it happens
Trigger: Calling Fetch/FetchAsync by UID with request.PartialRange set and a UID set so large (typically > ~1000 UIDs, Engine's per-command batch size) that MailKit splits it into multiple UID FETCH commands.
Common situations: Resuming download of a large mailbox with PartialRange while passing thousands of UIDs at once; resync jobs that pass UniqueIdRange covering every message combined with partial fetch.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- The IMAP server does not support the PARTIAL extension.
- The PARTIAL extension only supports UID-based FETCH…
- The ImapFolder does not support mod-sequences.
- 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/dbc5961bd254c3ec.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Imap/ImapFolderFetch.cs:1147
command.Append (')');
}
command.Append ("\r\n");
return command.ToString ();
}
IEnumerable<ImapCommand> CreateFetchCommands (IList<UniqueId> uids, IFetchRequest request, string command, CancellationToken cancellationToken)
{
var commands = Engine.CreateCommands (cancellationToken, this, command, uids);
if (request.PartialRange.HasValue) {
// Note: The PARTIAL fetch modifier applies to each FETCH command individually, so splitting the
// set of UIDs into multiple FETCH commands would change the semantics of the request.
var list = new List<ImapCommand> (commands);
if (list.Count > 1)
throw new NotSupportedException ("The set of unique identifiers is too large to fetch with a partial range.");
return list;
}
return commands;
}
static int EstimateInitialCapacity (IList<UniqueId> uids)
{
if (uids is UniqueIdRange || uids is UniqueIdSet) {
// UniqueIdRange is likely to refer to UIDs that have not yet been assigned or have been expunged,
// so cap our maximum initial capacity to 1024 (a reasonable limit?).
return Math.Min (uids.Count, 1024);
}
// If the user supplied an exact set of UIDs, then we'll assume they all exist
// and therefore we can use the capacity of `uids` as our initial capacity.
return uids.Count;View on GitHub (pinned to 9d3859a785)