jstedfast/MailKit · error · NotSupportedException

DIGEST-MD5 does not support SASL-IR.

Error message

DIGEST-MD5 does not support SASL-IR.

What it means

DIGEST-MD5 is a challenge/response mechanism that cannot send an initial response. SaslMechanismDigestMd5.Challenge throws NotSupportedException ('DIGEST-MD5 does not support SASL-IR.') when invoked with a null token, i.e. when asked to produce credentials before the server has issued its challenge.

Solutions

  1. Let the server issue the challenge first: do not use SASL-IR when the negotiated mechanism is DIGEST-MD5.
  2. Choose an IR-capable mechanism (PLAIN, SCRAM-SHA-1/256/512) if initial response is required.
  3. In custom protocol code, only pass the server's challenge bytes to Challenge(); treat null as invalid for this mechanism.

Example fix

// before
var mech = new SaslMechanismDigestMd5(uri, user, pass);
sendAuthCommand(mech.Challenge(null, 0, 0, ct)); // SASL-IR attempt
// after
var mech = new SaslMechanismDigestMd5(uri, user, pass);
var challenge = readServerChallenge();
sendAuthCommand(mech.Challenge(challenge, 0, challenge.Length, ct));
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the transport does not use SASL-IR for DIGEST-MD5
bool useInitialResponse = mech is not SaslMechanismDigestMd5;

Try / catch

try {
    client.Authenticate(uri, new SaslMechanismDigestMd5(uri, user, pass));
} catch (NotSupportedException) {
    client.Authenticate(uri, new SaslMechanismPlain(user, pass)); // over TLS
}

Prevention

When it happens

Trigger: Authenticating with SaslMechanismDigestMd5 over a protocol path that uses SASL Initial Client Response, or calling Challenge(null, ...) directly.

Common situations: Client libraries with 'send initial response' optimization enabled negotiating DIGEST-MD5; custom SASL engine that treats all mechanisms uniformly with IR.

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/0c9ff37eb078ea1f. Report an issue: GitHub.

Appendix: source

Thrown at MailKit/Security/SaslMechanismDigestMd5.cs:145

		/// </exception>
		/// <exception cref="System.OperationCanceledException">
		/// The operation was canceled via the cancellation token.
		/// </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;

View on GitHub (pinned to 9d3859a785)