jstedfast/MailKit · error · NotSupportedException

NotSupportedException

Error message

NotSupportedException

What it means

DuplexStream.Seek always throws NotSupportedException: a duplex pipe stream cannot reposition its read/write cursor. Seeking is fundamentally unsupported on this stream type, as documented via its exception cref.

Solutions

  1. Remove Seek usage; read strictly forward from the current position.
  2. Buffer the content into a MemoryStream first, then Seek on the buffer.
  3. Check stream.CanSeek before seeking and use a forward-only fallback.

Example fix

// before
stream.Seek (0, SeekOrigin.Begin);
// after
var buffered = new MemoryStream ();
stream.CopyTo (buffered);
buffered.Seek (0, SeekOrigin.Begin);
Defensive patterns

Strategy: validation

Validate before calling

if (stream.CanSeek) stream.Seek (0, SeekOrigin.Begin);
else { /* buffer first or read forward */ }

Type guard

bool SupportsSeek (Stream s) => s.CanSeek;

Try / catch

try { stream.Seek (offset, origin); } catch (NotSupportedException) { /* fall back to forward read */ }

Prevention

When it happens

Trigger: Calling Seek(offset, origin) on a DuplexStream, directly or indirectly via helpers like Position =, StreamReader with a nonzero buffer offset, or Stream.Seek-based rewinding.

Common situations: Passing the stream to parsers or utilities that call Seek to retry/reparse (e.g. MIME parsers expecting buffered streams); mixing code paths shared with FileStream.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at MailKit/DuplexStream.cs:363

		public override Task FlushAsync (CancellationToken cancellationToken)
		{
			CheckDisposed ();

			return OutputStream.FlushAsync (cancellationToken);
		}

		/// <summary>
		/// Sets the position within the current stream.
		/// </summary>
		/// <returns>The new position within the stream.</returns>
		/// <param name="offset">The offset into the stream relative to the <paramref name="origin"/>.</param>
		/// <param name="origin">The origin to seek from.</param>
		/// <exception cref="System.NotSupportedException">
		/// The stream does not support seeking.
		/// </exception>
		public override long Seek (long offset, SeekOrigin origin)
		{
			throw new NotSupportedException ();
		}

		/// <summary>
		/// Sets the length of the stream.
		/// </summary>
		/// <param name="value">The desired length of the stream in bytes.</param>
		/// <exception cref="System.NotSupportedException">
		/// The stream does not support setting the length.
		/// </exception>
		public override void SetLength (long value)
		{
			throw new NotSupportedException ();
		}

		/// <summary>
		/// Releases the unmanaged resources used by the <see cref="DuplexStream"/> and
		/// optionally releases the managed resources.
		/// </summary>

View on GitHub (pinned to 9d3859a785)