jstedfast/MailKit · error · SaslException

ChallengeTooLong

ChallengeTooLong

Error message

Server challenge too long.

What it means

RFC 2831 caps the DIGEST-MD5 challenge at 2048 bytes. SaslMechanismDigestMd5.Challenge throws SaslException with code SaslErrorCode.ChallengeTooLong when the server's initial challenge exceeds this limit, protecting against malformed or hostile servers.

Solutions

  1. Fix or report the server so it emits a compliant (<2048 bytes) DIGEST-MD5 challenge.
  2. Inspect the raw server response (network trace) to find what is inflating the challenge (banners, proxy injection) and remove the source.
  3. Catch SaslException, check ErrorCode == SaslErrorCode.ChallengeTooLong, and fall back to another mechanism (e.g. CRAM-MD5, PLAIN over TLS).

Example fix

// before
client.Authenticate(uri, new SaslMechanismDigestMd5(uri, user, pass)); // server challenge > 2048 bytes
// after
try {
    client.Authenticate(uri, new SaslMechanismDigestMd5(uri, user, pass));
} catch (SaslException ex) when (ex.ErrorCode == SaslErrorCode.ChallengeTooLong) {
    client.Authenticate(uri, new SaslMechanismCramMd5(user, pass));
}
Defensive patterns

Strategy: try-catch

Validate before calling

// client-side cannot validate before receipt; guard the exchange instead
// ensure no proxy/banner injection inflates the server's challenge

Try / catch

try {
    client.Authenticate(uri, new SaslMechanismDigestMd5(uri, user, pass));
} catch (SaslException ex) when (ex.ErrorCode == SaslErrorCode.ChallengeTooLong) {
    // non-conformant server; fall back
    client.Authenticate(uri, new SaslMechanismCramMd5(user, pass));
}

Prevention

When it happens

Trigger: Server sends a DIGEST-MD5 challenge whose encoded length is greater than 2048 bytes during the Auth state of the exchange.

Common situations: Misbehaving or non-conformant/proprietary servers that append extra data to the challenge, proxies injecting banners into the SASL exchange, garbage bytes on the socket being misinterpreted as a challenge.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at MailKit/Security/SaslMechanismDigestMd5.cs:148

		/// </exception>
		/// <exception cref="SaslException">
		/// An error has occurred while parsing the server's challenge token.
		/// </exception>
		protected override byte[]? Challenge (byte[]? token, int startIndex, int length, CancellationToken cancellationToken)
		{
			if (IsAuthenticated)
				return null;

			if (Uri is null)
				throw new InvalidOperationException ();

			switch (state) {
			case LoginState.Auth:
				if (token == null)
					throw new NotSupportedException ("DIGEST-MD5 does not support SASL-IR.");

				if (token.Length > 2048)
					throw new SaslException (MechanismName, SaslErrorCode.ChallengeTooLong, "Server challenge too long.");

				challenge = DigestChallenge.Parse (Encoding.UTF8.GetString (token, startIndex, length));
				encoding = challenge.Charset != null ? Encoding.UTF8 : TextEncodings.Latin1;
				cnonce ??= GenerateEntropy (15);

				response = new DigestResponse (challenge, encoding, Uri.Scheme, Uri.DnsSafeHost, AuthorizationId, Credentials.UserName, Credentials.Password, cnonce);
				state = LoginState.Final;

				return response.Encode (encoding);
			case LoginState.Final:
				if (token == null || token.Length == 0)
					throw new SaslException (MechanismName, SaslErrorCode.MissingChallenge, "Server response did not contain any authentication data.");

				var text = encoding!.GetString (token, startIndex, length);
				string? key, value;

				if (!DigestChallenge.TryParseKeyValuePair (text, out key, out value))
					throw new SaslException (MechanismName, SaslErrorCode.IncompleteChallenge, "Server response contained incomplete authentication data.");

View on GitHub (pinned to 9d3859a785)