jstedfast/MailKit · error · ArgumentOutOfRangeException
offset
Error message
offset
What it means
TryQueueGetStreamCommand (UID variant) throws ArgumentOutOfRangeException("offset") when offset < 0. The offset into the message stream must be non-negative to build a valid IMAP FETCH BODY[]<offset.size> section.
Solutions
- Clamp the computed offset with Math.Max(0, offset).
- Validate range arithmetic before calling the API.
- Use Math.Clamp or explicit checks when chunking message streams.
Example fix
// before var offset = summary.Length - chunkSize; var stream = folder.GetStream(uid, offset, chunkSize); // after var offset = Math.Max(0, summary.Length - chunkSize); var stream = folder.GetStream(uid, offset, chunkSize);
Defensive patterns
Strategy: validation
Validate before calling
offset = Math.Max(0, offset);
if (offset < 0) throw new InvalidOperationException("Offset computation failed."); Try / catch
try { stream = folder.GetStream(uid, offset, count); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "offset") { /* fix range math */ } Prevention
- Clamp all computed offsets with Math.Max(0, ...).
- Use checked arithmetic to catch underflow early.
- Unit-test chunk-boundary math for sizes smaller than the chunk.
When it happens
Trigger: Calling GetStream/GetStreamAsync (UID overload) with a negative offset (ImapFolderFetch.cs:4187), e.g. from integer underflow when computing a partial-range start.
Common situations: Computing offset as `total - chunkSize` when total < chunkSize; subtracting header size from a smaller value; uninitialized counter variables.
Related errors
- Specified argument was out of range of valid values…
- Specified argument was out of range of valid values…
- index
- count
- The specified threading algorithm is not supported.
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/4fc9b000d4075d73.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Imap/ImapFolderFetch.cs:4187
/// </exception>
public override Task<MimeEntity> GetBodyPartAsync (int index, BodyPart part, CancellationToken cancellationToken = default, ITransferProgress? progress = null)
{
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException (nameof (index));
if (part == null)
throw new ArgumentNullException (nameof (part));
return GetBodyPartAsync (index, part.PartSpecifier, cancellationToken, progress);
}
bool TryQueueGetStreamCommand (UniqueId uid, int offset, int count, CancellationToken cancellationToken, ITransferProgress? progress, [NotNullWhen (true)] out ImapCommand? ic, [NotNullWhen (true)] out FetchStreamContext? ctx)
{
if (!uid.IsValid)
throw new ArgumentException ("The uid is invalid.", nameof (uid));
if (offset < 0)
throw new ArgumentOutOfRangeException (nameof (offset));
if (count < 0)
throw new ArgumentOutOfRangeException (nameof (count));
CheckState (true, false);
if (count == 0) {
ctx = null;
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);
View on GitHub (pinned to 9d3859a785)