{"record":{"id":"1b9f8c2ce79a4f0f","repo":"jstedfast/MailKit","slug":"operation-is-not-valid-due-to-the-current-state-of-the-1b9f8c","errorCode":null,"errorMessage":"Operation is not valid due to the current state of the object.","messagePattern":"Operation is not valid due to the current state of the object\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"MailKit/Security/SaslMechanismDigestMd5.cs","lineNumber":140,"sourceCode":"\t\t/// <param name=\"startIndex\">The index into the token specifying where the server's challenge begins.</param>\n\t\t/// <param name=\"length\">The length of the server's challenge.</param>\n\t\t/// <param name=\"cancellationToken\">The cancellation token.</param>\n\t\t/// <exception cref=\"System.NotSupportedException\">\n\t\t/// The SASL mechanism does not support SASL-IR.\n\t\t/// </exception>\n\t\t/// <exception cref=\"System.OperationCanceledException\">\n\t\t/// The operation was canceled via the cancellation token.\n\t\t/// </exception>\n\t\t/// <exception cref=\"SaslException\">\n\t\t/// An error has occurred while parsing the server's challenge token.\n\t\t/// </exception>\n\t\tprotected override byte[]? Challenge (byte[]? token, int startIndex, int length, CancellationToken cancellationToken)\n\t\t{\n\t\t\tif (IsAuthenticated)\n\t\t\t\treturn null;\n\n\t\t\tif (Uri is null)\n\t\t\t\tthrow new InvalidOperationException ();\n\n\t\t\tswitch (state) {\n\t\t\tcase LoginState.Auth:\n\t\t\t\tif (token == null)\n\t\t\t\t\tthrow new NotSupportedException (\"DIGEST-MD5 does not support SASL-IR.\");\n\n\t\t\t\tif (token.Length > 2048)\n\t\t\t\t\tthrow new SaslException (MechanismName, SaslErrorCode.ChallengeTooLong, \"Server challenge too long.\");\n\n\t\t\t\tchallenge = DigestChallenge.Parse (Encoding.UTF8.GetString (token, startIndex, length));\n\t\t\t\tencoding = challenge.Charset != null ? Encoding.UTF8 : TextEncodings.Latin1;\n\t\t\t\tcnonce ??= GenerateEntropy (15);\n\n\t\t\t\tresponse = new DigestResponse (challenge, encoding, Uri.Scheme, Uri.DnsSafeHost, AuthorizationId, Credentials.UserName, Credentials.Password, cnonce);\n\t\t\t\tstate = LoginState.Final;\n\n\t\t\t\treturn response.Encode (encoding);\n\t\t\tcase LoginState.Final:","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/jstedfast/MailKit/blob/9d3859a7855e3e17582c07fd01972b8e262bf176/MailKit/Security/SaslMechanismDigestMd5.cs#L122-L158","documentation":"DIGEST-MD5 (RFC 2831) binds the digest computation to a URI (service type and host, e.g. 'imap/mail.example.com'). SaslMechanismDigestMd5.Challenge throws InvalidOperationException when the mechanism's Uri property is null because the digest response cannot be constructed without it.","triggerScenarios":"Instantiating SaslMechanismDigestMd5 and starting authentication without a Uri (using a constructor/property path that never sets it), then calling Challenge (directly or via Authenticate).","commonSituations":"Using a mechanism instance across contexts where the Uri was never provided, constructing the mechanism manually for a custom SASL host instead of via SmtpClient/ImapClient (which set the Uri from the connection).","solutions":["Use the SaslMechanismDigestMd5(Uri uri, ...) constructor overload that supplies the service URI instead of the bare credentials constructor.","Authenticate through SmtpClient/ImapClient/Pop3Client, which automatically set the mechanism's Uri from the server being connected to.","Null-check Uri before calling Challenge in custom SASL drivers and construct the mechanism with the correct uri (scheme + host of the service)."],"exampleFix":"// before\nvar mech = new SaslMechanismDigestMd5(user, pass); // Uri is null\n// after\nvar mech = new SaslMechanismDigestMd5(new Uri(\"imap://mail.example.com\"), user, pass);","handlingStrategy":"validation","validationCode":"if (mech.Uri == null)\n    throw new InvalidOperationException(\"DIGEST-MD5 requires a service URI; use the (Uri, user, pass) constructor.\");","typeGuard":null,"tryCatchPattern":"try {\n    client.Authenticate(uri, mech);\n} catch (InvalidOperationException) {\n    mech = new SaslMechanismDigestMd5(uri, user, pass);\n    client.Authenticate(uri, mech);\n}","preventionTips":["Always construct SaslMechanismDigestMd5 with the Uri overload","Authenticate via SmtpClient/ImapClient/Pop3Client so the Uri is set automatically","Don't reuse mechanism instances created without a Uri"],"tags":["sasl","digest-md5","invalid-state","uri"],"backgroundTag":"invalid-state-transition","analyzedSha":"9d3859a7855e3e17582c07fd01972b8e262bf176","analyzedAt":"2026-09-15T15:46:11.592Z","contentChangedAt":"2026-09-15T15:46:11.592Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}