jstedfast/MailKit · error · ArgumentException

The uid is invalid.

Error message

The uid is invalid.

What it means

MailFolder.GetStream(UniqueId, BodyPart, ...) validates that the UniqueId passed for the message is a valid (non-zero, well-formed) UID before issuing the FETCH command. An invalid UniqueId means the value was never assigned from a message summary (its Id is 0 / IsValid is false), so the library throws ArgumentException instead of sending a meaningless IMAP command.

Solutions

  1. Populate the UniqueId from the message itself, e.g. folder.GetUID(index) or the Indexer/MessageSummary property (summary.UniqueId), before calling GetStream.
  2. Check `uid.IsValid` before calling and skip or log the message if false.
  3. If the message came from a body-part enumeration, keep the UniqueId from the same MessageSummary that produced the BodyPart.
  4. When resuming saved state, persist and restore the UIDVALIDITY and UIDs; re-fetch the summary if UIDs cannot be trusted.

Example fix

// before
var uid = new UniqueId();
var stream = folder.GetStream(uid, bodyPart);
// after
var uid = folder.GetUID(index);
if (!uid.IsValid) throw new InvalidOperationException($"No UID for message at index {index}");
var stream = folder.GetStream(uid, bodyPart);
Defensive patterns

Strategy: validation

Validate before calling

if (uid == null || !uid.IsValid)
    throw new InvalidOperationException("Cannot fetch stream: the UniqueId has not been populated (use summary.UniqueId or folder.GetUID(index)).");

Type guard

bool IsUsableUid(UniqueId uid) => uid.IsValid;

Try / catch

try {
    var stream = folder.GetStream(uid, bodyPart);
} catch (ArgumentException ex) when (ex.ParamName == "uid") {
    logger.LogWarning(ex, "Invalid UID supplied; refetching summaries");
    summaries = folder.Fetch(0, -1, MessageSummaryItems.UniqueId | MessageSummaryItems.BodyStructure);
}

Prevention

When it happens

Trigger: Calling MailFolder.GetStream(uid, bodyPart) with a UniqueId that was default-constructed (UniqueId.Invalid, Id == 0) or copied from a source where it was never populated.

Common situations: Constructing `new UniqueId()` as a placeholder; deserializing message identifiers from storage where the UID was lost; fetching a BodyPart from a summary list but pairing it with an unrelated/empty uid variable.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at MailKit/MailFolder.cs:5973

		/// <exception cref="MessageNotFoundException">
		/// The <see cref="IMailStore"/> did not return the requested message stream.
		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </exception>
		/// <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, 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));

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

		/// <summary>
		/// Asynchronously get a body part as a stream.
		/// </summary>
		/// <remarks>
		/// Asynchronously gets a body part as a stream.
		/// </remarks>
		/// <example>
		/// <code language="c#" source="Examples\ImapBodyPartExamples.cs" region="GetBodyPartStreamsByUniqueId"/>
		/// </example>
		/// <returns>The body part stream.</returns>
		/// <param name="uid">The UID of the message.</param>

View on GitHub (pinned to 9d3859a785)