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
- Let the server issue the challenge first: do not use SASL-IR when the negotiated mechanism is DIGEST-MD5.
- Choose an IR-capable mechanism (PLAIN, SCRAM-SHA-1/256/512) if initial response is required.
- 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
- Wait for the server challenge before invoking Challenge for DIGEST-MD5
- Configure clients to skip initial-response for non-IR mechanisms
- Prefer SCRAM/PLAIN when SASL-IR is required by the transport
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
- CRAM-MD5 does not support SASL-IR.
- Operation is not valid due to the current state of the…
- ChallengeTooLong
- MissingChallenge
- IncompleteChallenge
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)