jstedfast/MailKit · error · NotSupportedException

No compatible authentication mechanisms found.

Error message

No compatible authentication mechanisms found.

What it means

AsyncSmtpClient.AuthenticateAsync tries each SASL mechanism the server advertised and that the client supports. If nothing was tried at all - because the server advertised no mechanisms that intersect with MailKit's supported set and no fallback was possible - it throws NotSupportedException with this message.

Solutions

  1. Check SmtpClient.AuthenticationMechanisms after connecting to see what the server offers.
  2. Remove the client-side mechanism restriction (the useAuthMechanisms/Capabilities filter) so MailKit may use a mechanism the server actually advertises.
  3. Fix the server configuration to advertise a standard mechanism (PLAIN, LOGIN, CRAM-MD5, XOAUTH2).
  4. If no AUTH is offered because the server auto-trusts your IP, skip calling AuthenticateAsync.

Example fix

// before
client.Authenticated += ...; await client.AuthenticateAsync(user, pass); // server advertises only GSSAPI
// after
if (client.AuthenticationMechanisms.Contains("PLAIN"))
    await client.AuthenticateAsync(user, pass);
else
    throw new Exception($"No usable auth mechanism; server offers: {string.Join(",", client.AuthenticationMechanisms)}");
Defensive patterns

Strategy: validation

Validate before calling

await client.ConnectAsync(host, port, options);
var supported = client.AuthenticationMechanisms;
if (supported.Count == 0)
    throw new InvalidOperationException("Server advertises no AUTH mechanisms; cannot authenticate");
var usable = supported.Intersect(new[] { "PLAIN", "LOGIN", "CRAM-MD5", "XOAUTH2", "NTLM", "DIGEST-MD5" }).ToList();
if (usable.Count == 0)
    throw new InvalidOperationException($"No mutually supported SASL mechanism. Server offers: {string.Join(", ", supported)}");

Type guard

bool CanAuthenticate(SmtpClient c) => c.IsConnected && c.AuthenticationMechanisms.Count > 0;

Try / catch

try {
    await client.AuthenticateAsync(user, token);
} catch (NotSupportedException ex) {
    throw new ApplicationException($"No compatible SASL mechanism; server offers: {string.Join(",", client.AuthenticationMechanisms)}", ex);
} catch (AuthenticationException ex) {
    // credentials wrong - different problem, handle separately
    throw;
}

Prevention

When it happens

Trigger: Calling AuthenticateAsync against a server whose EHLO response lists no AUTH mechanisms (or only mechanisms MailKit lacks, and its preferred fallback mechanism is not in the server's list).

Common situations: Connecting to an SMTP relay that requires pre-authentication by IP (no AUTH advertised); servers offering only exotic mechanisms; server misconfigured without an AUTH mechanism plugin.

Understand the failure class

Related errors


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

Appendix: source

Thrown at MailKit/Net/Smtp/AsyncSmtpClient.cs:415

						OnAuthenticated (response.Response);
						return;
					}

					var message = string.Format (CultureInfo.InvariantCulture, "{0}: {1}", (int) response.StatusCode, response.Response);
					Exception inner;

					if (saslException != null)
						inner = new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response, saslException);
					else
						inner = new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);

					authException = new AuthenticationException (message, inner);
				}

				if (tried)
					throw authException ?? new AuthenticationException ();

				throw new NotSupportedException ("No compatible authentication mechanisms found.");
			} catch (Exception ex) {
				operation.SetError (ex);
				throw;
			}
		}

		async Task SslHandshakeAsync (SslStream ssl, string host, CancellationToken cancellationToken)
		{
#if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
			await ssl.AuthenticateAsClientAsync (GetSslClientAuthenticationOptions (host, ValidateRemoteCertificate), cancellationToken).ConfigureAwait (false);
#else
			await ssl.AuthenticateAsClientAsync (host, ClientCertificates, SslProtocols, CheckCertificateRevocation).ConfigureAwait (false);
#endif
		}

		async Task PostConnectAsync (Stream stream, string host, int port, SecureSocketOptions options, bool starttls, CancellationToken cancellationToken)
		{
			clientConnectedTimestamp = Stopwatch.GetTimestamp ();

View on GitHub (pinned to 9d3859a785)