jstedfast/MailKit · error · AuthenticationException
No credentials could be found for the POP3 server.
Error message
No credentials could be found for the POP3 server.
What it means
During Pop3Client AuthenticateAsync, after SASL mechanisms fail to match, MailKit falls back to classic USER/PASS using credentials from the supplied ICredentialsProvider. If GetCredential returns null for the POP3 server URI, it throws AuthenticationException meaning no usable credentials were found at all.
Solutions
- Call AuthenticateAsync with a concrete user/password pair (string, string) or a NetworkCredential instead of an unmatched CredentialCache.
- If using a CredentialCache, register the credential with the exact host name and port used in Connect (Uri-based match).
- Verify username/password are non-empty and loaded before calling Authenticate; check configuration loading order.
Example fix
// before
var cache = new CredentialCache();
cache.Add(new Uri("pop://mail.example.com"), "DEFAULT", cred);
await client.AuthenticateAsync(cache); // URI mismatch -> no credentials
// after
await client.AuthenticateAsync(new NetworkCredential("user", "pass"));
// or: cache.Add(new Uri("pop://mail.example.com:995"), "DEFAULT", cred); Defensive patterns
Strategy: validation
Validate before calling
// ensure credentials exist before connecting
if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
throw new InvalidOperationException("POP3 credentials are not configured"); Try / catch
try { await client.AuthenticateAsync(cred); }
catch (AuthenticationException ex) when (ex.Message.Contains("No credentials could be found")) {
// fall back to explicitly supplied credentials or fail with a config error
await client.AuthenticateAsync(configuredUser, configuredPass);
} Prevention
- Pass NetworkCredential or (user, pass) strings rather than sparse CredentialCache entries
- Match CredentialCache URI scheme/host/port exactly to the Connect target
- Load and verify credentials from configuration before calling Authenticate
When it happens
Trigger: Calling client.AuthenticateAsync without credentials, or with an ICredentialsProvider (e.g. CredentialCache) that has no entry matching the POP3 server URI and 'DEFAULT'/auth-type, and no SASL mechanism supplying credentials.
Common situations: Passing a NetworkCredential directly is fine, but passing a CredentialCache registered under a different host/port/scheme; empty username/password; credentials not yet loaded from configuration at call time.
Related errors
- No credentials could be found for the POP3 server.
- Value cannot be null. (Parameter 'userName')
- Value cannot be null. (Parameter 'password')
- No credentials could be found for the IMAP server.
- The Pop3Client has not been authenticated.
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/1270ce4f831918b5.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Pop3/AsyncPop3Client.cs:279
cancellationToken.ThrowIfCancellationRequested ();
var ctx = GetSaslAuthContext (sasl, saslUri);
var pc = await ctx.AuthenticateAsync (cancellationToken).ConfigureAwait (false);
if (pc.Status == Pop3CommandStatus.Error)
continue;
pc.ThrowIfError ();
await OnAuthenticatedAsync (ctx.AuthMessage!, cancellationToken).ConfigureAwait (false);
return;
}
}
// fall back to the classic USER & PASS commands...
if ((cred = credentials.GetCredential (saslUri, "DEFAULT")) == null)
throw new AuthenticationException ("No credentials could be found for the POP3 server.");
userName = utf8 ? SaslMechanism.SaslPrep (cred.UserName) : cred.UserName;
password = utf8 ? SaslMechanism.SaslPrep (cred.Password) : cred.Password;
detector.IsAuthenticating = true;
try {
await SendCommandAsync (cancellationToken, encoding, "USER {0}\r\n", userName).ConfigureAwait (false);
message = await SendCommandAsync (cancellationToken, encoding, "PASS {0}\r\n", password).ConfigureAwait (false);
} catch (Pop3CommandException) {
throw new AuthenticationException ();
} finally {
detector.IsAuthenticating = false;
}
await OnAuthenticatedAsync (message, cancellationToken).ConfigureAwait (false);
} catch (Exception ex) {
operation.SetError (ex);
throw;View on GitHub (pinned to 9d3859a785)