jstedfast/MailKit · error · ArgumentOutOfRangeException

index

Error message

index

What it means

ArgumentOutOfRangeException (message is the parameter name "index") thrown by QueueGetHeadersCommand when the sequence index passed to GetHeaders(int index, ...) is negative or >= folder.Count. The IMAP FETCH command needs a 1-based message sequence number within the currently selected folder, so out-of-range values are rejected before any command is sent.

Solutions

  1. Validate `index >= 0 && index < folder.Count` immediately before calling GetHeaders.
  2. Re-read folder.Count after any open/fetch/expunge, since the count changes as messages arrive or are removed.
  3. Use MessageSummary-based workflows: fetch summaries first, then GetHeaders(summary.Index).

Example fix

// before
for (int i = 0; i <= folder.Count; i++)
    Process(folder.GetHeaders(i));

// after
for (int i = 0; i < folder.Count; i++)
    Process(folder.GetHeaders(i));
Defensive patterns

Strategy: validation

Validate before calling

if (index < 0 || index >= folder.Count)
    throw new ArgumentOutOfRangeException(nameof(index), "Index must be within the current folder's message count.");

Type guard

bool IsValidIndex(IMailFolder folder, int index) => (uint)index < (uint)folder.Count;

Try / catch

try { var headers = folder.GetHeaders(index, specifier); }
catch (ArgumentOutOfRangeException) { /* clamp to folder.Count - 1 or refresh folder */ }

Prevention

When it happens

Trigger: Calling GetHeaders(int index, ...) with an index captured before messages were expunged, an index >= folder.Count, or a plain 0-based loop index passed to the API (which expects 0-based but bounded by Count).

Common situations: Iterating with `for (int i = 0; i <= folder.Count; i++)` (off-by-one); reusing indexes after a fetch summary refresh removed messages; using an index from a different, previously opened folder state.

Related errors


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

Appendix: source

Thrown at MailKit/Net/Imap/ImapFolderFetch.cs:3053

		public override async Task<HeaderList> GetHeadersAsync (int index, CancellationToken cancellationToken = default, ITransferProgress? progress = null)
		{
			var ic = QueueGetHeadersCommand (index, cancellationToken, progress, out var ctx);

			try {
				await Engine.RunAsync (ic).ConfigureAwait (false);

				var stream = ProcessGetHeadersResponse (ic, ctx, index);

				return await ParseHeadersAsync (stream, cancellationToken).ConfigureAwait (false);
			} finally {
				ctx.Dispose ();
			}
		}

		ImapCommand QueueGetHeadersCommand (int index, string partSpecifier, CancellationToken cancellationToken, ITransferProgress? progress, out FetchStreamContext ctx, out string[] tags)
		{
			if (index < 0 || index >= Count)
				throw new ArgumentOutOfRangeException (nameof (index));

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

			CheckState (true, false);

			var command = string.Format ("FETCH {0} ({1})\r\n", index + 1, GetBodyPartQuery (partSpecifier, true, out tags));
			var ic = new ImapCommand (Engine, cancellationToken, this, command);
			ic.RegisterUntaggedHandler ("FETCH", FetchStreamHandler);
			ic.UserData = ctx = new FetchStreamContext (progress);

			Engine.QueueCommand (ic);

			return ic;
		}

		Stream ProcessGetHeadersResponse (ImapCommand ic, FetchStreamContext ctx, int index, string[] tags)
		{

View on GitHub (pinned to 9d3859a785)