jstedfast/MailKit · error · ArgumentOutOfRangeException

Specified argument was out of the range of valid values.

Error message

Specified argument was out of the range of valid values.

What it means

NtlmMessageBase.ValidateArguments() throws ArgumentOutOfRangeException when decoding an NTLM message byte array with a startIndex that is negative or beyond the end of the buffer. The library validates all positional arguments before parsing any message fields, since reading outside the buffer would produce garbage or crash. It guards every call to Decode-style methods (e.g. NtlmChallengeResponse.Decode, NtlmAuthenticate.Decode).

Solutions

  1. Verify startIndex is >= 0 and <= message.Length before calling the decode API
  2. Recompute the offset from the actual buffer (e.g. use message.Length instead of a hard-coded constant)
  3. If parsing a sub-message, slice with ArraySegment or copy the correct region first

Example fix

// before
msg.Decode(buffer, offset, buffer.Length - offset); // offset from wrong frame
// after
if (offset < 0 || offset > buffer.Length)
    throw new InvalidOperationException("bad NTLM offset");
msg.Decode(buffer, offset, buffer.Length - offset);
Defensive patterns

Strategy: validation

Validate before calling

if (message == null) throw new ArgumentNullException(nameof(message));
if (startIndex < 0 || startIndex > message.Length)
    throw new ArgumentOutOfRangeException(nameof(startIndex));

Type guard

static bool IsValidRange(byte[] buf, int start) => buf != null && start >= 0 && start <= buf.Length;

Try / catch

try { msg.Decode(buffer, startIndex, length); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "startIndex") { /* fix offset / skip message */ }

Prevention

When it happens

Trigger: Calling a decode/parse API (e.g. NtlmChallengeResponse.Decode or a Type1/Type2/Type3 message Load) with a startIndex < 0 or startIndex > message.Length on the supplied byte[].

Common situations: Passing a wrong slice offset after manually splitting an NTLM handshake buffer; reusing a stale startIndex after the buffer was re-sliced or shortened; off-by-one when skipping a fixed-size header.

Related errors


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

Appendix: source

Thrown at MailKit/Security/Ntlm/NtlmMessageBase.cs:87

		{
			for (int i = 0; i < Signature.Length; i++) {
				if (message[startIndex + i] != Signature[i])
					return false;
			}

			return BitConverterLE.ToUInt32 (message, startIndex + 8) == Type;
		}

		protected void ValidateArguments (byte[] message, int startIndex, int length)
		{
			if (message == null)
				throw new ArgumentNullException (nameof (message));

			if (startIndex < 0 || startIndex > message.Length)
				throw new ArgumentOutOfRangeException (nameof (startIndex));

			if (length < 12 || length > (message.Length - startIndex))
				throw new ArgumentOutOfRangeException (nameof (length));

			if (!CheckSignature (message, startIndex))
				throw new ArgumentException (string.Format (CultureInfo.InvariantCulture, "Invalid Type{0} message.", Type), nameof (message));

			var messageType = BitConverterLE.ToUInt32 (message, 8);
			if (messageType != Type)
				throw new ArgumentException (string.Format (CultureInfo.InvariantCulture, "Invalid Type{0} message.", Type), nameof (message));
		}

		public abstract byte[] Encode ();
	}
}

View on GitHub (pinned to 9d3859a785)