jstedfast/MailKit · error · ArgumentOutOfRangeException
ArgumentOutOfRangeException
Error message
ArgumentOutOfRangeException
What it means
ValidateArguments guards DuplexStream.Read/ReadAsync/Write/WriteAsync. It throws ArgumentOutOfRangeException when offset is negative or beyond buffer.Length, or when count is negative or exceeds buffer.Length - offset. It ensures read/write operations never access memory outside the supplied buffer.
Solutions
- Clamp or validate offset and count against buffer.Length before the call: 0 <= offset <= buffer.Length and 0 <= count <= buffer.Length - offset.
- Fix the arithmetic that computes offset/count (check for subtraction underflow producing negatives).
- If values come from external input, validate them at the boundary with a clear error message.
Example fix
// before stream.Read (buffer, offset, count); // after if (offset < 0 || offset > buffer.Length) throw new ArgumentException (nameof (offset)); if (count < 0 || count > buffer.Length - offset) throw new ArgumentException (nameof (count)); stream.Read (buffer, offset, count);
Defensive patterns
Strategy: validation
Validate before calling
static bool IsValidWindow (byte[] buffer, int offset, int count) =>
buffer != null && offset >= 0 && offset <= buffer.Length && count >= 0 && count <= buffer.Length - offset; Type guard
bool ValidBufferArgs (byte[] b, int off, int cnt) => b != null && off >= 0 && off <= b.Length && cnt >= 0 && cnt <= b.Length - off;
Try / catch
try { stream.Read (buffer, offset, count); } catch (ArgumentOutOfRangeException ex) { /* log ex.ParamName: offset or count */ } Prevention
- Centralize buffer-window math in one validated helper instead of repeating arithmetic at call sites.
- Beware of computed offsets after resizing buffers; recompute count = buffer.Length - offset.
- Validate externally supplied offset/count at the API boundary.
When it happens
Trigger: Calling Read/Write (or their async forms) on a DuplexStream with a negative offset, offset > buffer.Length, negative count, or count > buffer.Length - offset.
Common situations: Off-by-one buffer math; reusing buffer-size constants after changing buffer allocation; passing a user-supplied offset/count straight through without clamping.
Related errors
- ObjectDisposedException
- NotSupportedException
- Specified argument was out of range of valid values…
- Specified argument was out of range of valid values…
- arrayIndex
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/b99049be3f9f45e4.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/DuplexStream.cs:164
/// <returns>A long value representing the length of the stream in bytes.</returns>
/// <value>The length of the stream.</value>
/// <exception cref="System.NotSupportedException">
/// The stream does not support seeking.
/// </exception>
public override long Length {
get { throw new NotSupportedException (); }
}
static void ValidateArguments (byte[] buffer, int offset, int count)
{
if (buffer == null)
throw new ArgumentNullException (nameof (buffer));
if (offset < 0 || offset > buffer.Length)
throw new ArgumentOutOfRangeException (nameof (offset));
if (count < 0 || count > (buffer.Length - offset))
throw new ArgumentOutOfRangeException (nameof (count));
}
void CheckDisposed ()
{
if (disposed)
throw new ObjectDisposedException (nameof (DuplexStream));
}
/// <summary>
/// Reads a sequence of bytes from the stream and advances the position
/// within the stream by the number of bytes read.
/// </summary>
/// <returns>The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many
/// bytes are not currently available, or zero (0) if the end of the stream has been reached.</returns>
/// <param name="buffer">The buffer.</param>
/// <param name="offset">The buffer offset.</param>
/// <param name="count">The number of bytes to read.</param>
/// <exception cref="System.ArgumentNullException">View on GitHub (pinned to 9d3859a785)