jstedfast/MailKit · error · ArgumentOutOfRangeException

offset

Error message

offset

What it means

MailFolder.GetStream(UniqueId uid, BodyPart part, int offset, int count, ...) throws ArgumentOutOfRangeException with the message "offset" when a negative byte offset into the body part's stream is supplied. The library requires offsets to be zero or positive because they are forwarded to the IMAP server as a partial-fetch start position; a negative value has no meaning in the protocol.

Solutions

  1. Verify the offset is >= 0 before calling GetStream and clamp or reject negative values
  2. Fix the arithmetic that produces the offset (e.g. Math.Max(0, chunkStart - overlap))
  3. Ensure the value passed is the byte offset within the part, not a message index or UID

Example fix

// before
await folder.GetStream(uid, part, offset, count);
// after
if (offset < 0) throw new ArgumentException("Offset must be >= 0");
await folder.GetStream(uid, part, Math.Max(0, offset), count);
Defensive patterns

Strategy: validation

Validate before calling

if (offset < 0) throw new ArgumentException("offset must be >= 0", nameof(offset));

Type guard

static bool IsValidOffset(int offset) => offset >= 0;

Try / catch

try {
    var stream = folder.GetStream(uid, part, offset, count);
} catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "offset") {
    // fix offset and retry
}

Prevention

When it happens

Trigger: Calling MailFolder.GetStream(uid, part, offset, count) with offset < 0, typically the result of a bad variable, an unvalidated subtraction (e.g. chunkStart - chunkOverlap with chunkOverlap > chunkStart), or an uninitialized int defaulting below zero.

Common situations: Implementing resumable/partial downloads where chunk math goes negative on the first chunk; computing offsets from parsed message size fields that failed; copying offset logic from a sync/async overload that had a different coordinate convention.

Related errors


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

Appendix: source

Thrown at MailKit/MailFolder.cs:6212

		/// <exception cref="System.IO.IOException">
		/// An I/O error occurred.
		/// </exception>
		/// <exception cref="ProtocolException">
		/// The server's response contained unexpected tokens.
		/// </exception>
		/// <exception cref="CommandException">
		/// The command failed.
		/// </exception>
		public virtual Stream GetStream (UniqueId uid, BodyPart part, int offset, int count, CancellationToken cancellationToken = default, ITransferProgress? progress = null)
		{
			if (!uid.IsValid)
				throw new ArgumentException ("The uid is invalid.", nameof (uid));

			if (part == null)
				throw new ArgumentNullException (nameof (part));

			if (offset < 0)
				throw new ArgumentOutOfRangeException (nameof (offset));

			if (count < 0)
				throw new ArgumentOutOfRangeException (nameof (count));

			return GetStream (uid, part.PartSpecifier, offset, count, cancellationToken, progress);
		}

		/// <summary>
		/// Asynchronously get a substream of the specified body part.
		/// </summary>
		/// <remarks>
		/// Asynchronously gets a substream of the body part. If the starting offset is beyond
		/// the end of the body part, an empty stream is returned. If the number of
		/// bytes desired extends beyond the end of the body part, a truncated stream
		/// will be returned.
		/// </remarks>
		/// <returns>The stream.</returns>
		/// <param name="uid">The UID of the message.</param>

View on GitHub (pinned to 9d3859a785)