jstedfast/MailKit · error · SmtpCommandException
MessageNotAccepted
MessageNotAccepted
Error message
No recipients were accepted.
What it means
During SendAsync, after RCPT TO is issued for each recipient, MailKit counts how many were accepted. If zero recipients were accepted by the server, it fires OnNoRecipientsAccepted and throws SmtpCommandException with SmtpStatusCode.TransactionFailed and this message, because the DATA/BDAT phase cannot proceed without at least one recipient.
Solutions
- Inspect the RCPT TO failures (SmtpClient.RecipientsAccepted / the per-recipient exceptions) to see why each was rejected.
- Verify the message has valid recipients in To/Cc/Bcc before sending.
- Ensure SMTP authentication succeeded and the account has relay rights.
- Handle the SmtpCommandException (code MessageNotAccepted) and check NoRecipientsAccepted event details.
Example fix
// before
await client.SendAsync(message); // message.To is empty
// after
if (!message.To.Any() && !message.Cc.Any() && !message.Bcc.Any())
throw new InvalidOperationException("Message has no recipients");
await client.SendAsync(message); Defensive patterns
Strategy: validation
Validate before calling
bool hasRecipients = message.To.Count + message.Cc.Count + message.Bcc.Count > 0;
if (!hasRecipients)
throw new InvalidOperationException("Cannot send: message has no recipients"); Type guard
bool HasValidRecipients(MimeMessage m) => m != null && (m.To.Any(a => a is MailboxAddress mb && MailboxAddress.IsValid(mb.Address)) || m.Cc.Any() || m.Bcc.Any());
Try / catch
try {
await client.SendAsync(message);
} catch (SmtpCommandException ex) when (ex.ErrorCode == SmtpErrorCode.MessageNotAccepted) {
logger.LogWarning("All recipients rejected: {Message}", ex.Message);
// inspect per-recipient failures / NoRecipientsAccepted event data before retrying
} Prevention
- Validate recipients with MailboxAddress.TryParse before sending
- Ensure authentication succeeded so the server permits relay
- Subscribe to the NoRecipientsAccepted event for diagnostics
- Check per-recipient RCPT failures instead of assuming all-or-nothing
When it happens
Trigger: Calling SendAsync when every RCPT TO was rejected - e.g. Message.To/Cc/Bcc all empty, all recipients invalid, relay denied, or server rejecting each address with a permanent error.
Common situations: Sending mail where the recipient list was filtered to empty beforehand; authenticated user lacks relay permission; domain not accepted by the server; anti-spam rejection of all recipients.
Related errors
- The SmtpClient must be connected before you can send…
- No compatible authentication mechanisms found.
- The SMTP server does not support the STARTTLS extension.
- The SmtpClient is not connected.
- Value cannot be null. (Parameter 'message')
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/5a11a0bc74db7be7.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Smtp/AsyncSmtpClient.cs:1015
if (await RcptToAsync (format, message, recipients[i], pipeline, cancellationToken).ConfigureAwait (false))
recipientsAccepted++;
}
if (queued.Count > 0) {
// Note: if PIPELINING is supported, this will flush all outstanding
// MAIL FROM and RCPT TO commands to the server and then process
// all of their responses.
var results = await FlushCommandQueueAsync (message, sender, recipients, cancellationToken).ConfigureAwait (false);
recipientsAccepted = results.RecipientsAccepted;
if (results.FirstException != null)
throw results.FirstException;
}
if (recipientsAccepted == 0) {
OnNoRecipientsAccepted (message);
throw new SmtpCommandException (SmtpErrorCode.MessageNotAccepted, SmtpStatusCode.TransactionFailed, "No recipients were accepted.");
}
if (bdat)
return await BdatAsync (format, message, size, cancellationToken, progress).ConfigureAwait (false);
var dataResponse = await Stream.SendCommandAsync ("DATA\r\n", cancellationToken).ConfigureAwait (false);
ParseDataResponse (dataResponse);
return await MessageDataAsync (format, message, size, cancellationToken, progress).ConfigureAwait (false);
} catch (ServiceNotAuthenticatedException ex) {
operation.SetError (ex);
// do not disconnect
await ResetAsync (cancellationToken).ConfigureAwait (false);
throw;
} catch (SmtpCommandException ex) {
operation.SetError (ex);View on GitHub (pinned to 9d3859a785)