jstedfast/MailKit · error · MessageNotFoundException
The IMAP server did not return the requested stream.
Error message
The IMAP server did not return the requested stream.
What it means
ProcessGetStreamResponse (UID variant) throws MessageNotFoundException when the server's FETCH response does not contain the requested section for the UID. The library asked for BODY[]<offset.count> but the server returned nothing usable, so the requested stream cannot be provided.
Solutions
- Catch MessageNotFoundException and treat as the message no longer existing; refresh summaries.
- Verify the message still exists (folder.GetUid / Fetch) before streaming.
- Retry once after refreshing the folder's summary state.
- Test against a known-conformant server (e.g. Dovecot) to isolate server quirks.
Example fix
// before
var stream = folder.GetStream(uid, offset, count);
// after
try {
stream = folder.GetStream(uid, offset, count);
} catch (MessageNotFoundException) {
folder.Fetch((int)0, -1, MessageSummaryItems.UniqueId | MessageSummaryItems.Size, null);
} Defensive patterns
Strategy: try-catch
Validate before calling
var summary = folder.GetSummary(uid); // or verify message still listed in summaries if (summary is null) return null;
Try / catch
try { stream = folder.GetStream(uid, offset, count); }
catch (MessageNotFoundException) {
folder.Fetch(0, -1, MessageSummaryItems.UniqueId | MessageSummaryItems.Size, null);
return null; // message vanished server-side
} Prevention
- Handle FolderExpunged/MessagesVanished events to keep state fresh.
- Prefer UID overloads so stale items are detectable.
- Treat missing streams as transient and re-sync before retrying once.
- Test against a conformant server (Dovecot) to rule out server quirks.
When it happens
Trigger: Calling GetStream(uid, ...) where ctx.TryGetSection(uid, ...) fails after ProcessFetchResponse (ImapFolderFetch.cs:4214) - the server omitted the section, returned BADCHARSET/nil data, or the message was expunged between request and response.
Common situations: Servers (or proxies) that silently skip truncated/invalid BODY[] sections; message deleted concurrently by another client; nonconformant IMAP servers returning partial FETCH responses.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- The IMAP server did not return the requested message…
- The IMAP server did not return the requested body part…
- The IMAP server did not return the requested message.
- The IMAP server did not return the requested body part.
- Value cannot be null. (Parameter 'name')
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/5d1e21dfd0df0b23.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Imap/ImapFolderFetch.cs:4214
ic = null;
return false;
}
ic = new ImapCommand (Engine, cancellationToken, this, "UID FETCH %u (BODY.PEEK[]<%d.%d>)\r\n", uid.Id, offset, count);
ic.RegisterUntaggedHandler ("FETCH", FetchStreamHandler);
ic.UserData = ctx = new FetchStreamContext (progress);
Engine.QueueCommand (ic);
return true;
}
Stream ProcessGetStreamResponse (ImapCommand ic, FetchStreamContext ctx, UniqueId uid)
{
ProcessFetchResponse (ic);
if (!ctx.TryGetSection (uid, string.Empty, out var section, true))
throw new MessageNotFoundException ("The IMAP server did not return the requested stream.");
return section.Stream;
}
/// <summary>
/// Get a substream of the specified message.
/// </summary>
/// <remarks>
/// Fetches a substream of the message. If the starting offset is beyond
/// the end of the message, an empty stream is returned. If the number of
/// bytes desired extends beyond the end of the message, the stream will
/// end where the message ends.
/// </remarks>
/// <returns>The stream.</returns>
/// <param name="uid">The UID of the message.</param>
/// <param name="offset">The starting offset of the first desired byte.</param>
/// <param name="count">The number of bytes desired.</param>
/// <param name="cancellationToken">The cancellation token.</param>View on GitHub (pinned to 9d3859a785)