ellite/Wallos · error · Exception
$this->lang('recipients_failed') . $errstr
Error message
$this->lang('recipients_failed') . $errstr What it means
Thrown in smtpSend() after the DATA phase when one or more recipients were rejected by the server (collected in $bad_rcpt with their per-recipient SMTP errors). The exception message concatenates the localized 'recipients_failed' string with 'address: error' pairs. Unlike other SMTP errors this is STOP_CONTINUE, so per-recipient failures can still allow partial delivery to accepted recipients before the exception surfaces.
Solutions
- Read $mailer->ErrorInfo / the exception message: it lists each failed address with the server's error code.
- Validate recipient addresses before sending (filter_var($email, FILTER_VALIDATE_EMAIL), or verify the mailbox exists).
- Remove or correct rejected addresses from the recipient list and retry for the remaining recipients.
- If relay is denied (554/550 relay access denied), authenticate properly or use the correct relay host for external recipients.
- Check for typos and stale addresses in your mailing list source (hard bounces).
Example fix
// before
$mailer->addAddress('user@gmial.com'); // typo: rejected 550
$mailer->send();
// after
$rcpt = 'user@gmail.com';
if (filter_var($rcpt, FILTER_VALIDATE_EMAIL)) {
$mailer->addAddress($rcpt);
}
$mailer->send(); Defensive patterns
Strategy: validation
Validate before calling
foreach ($recipients as $rcpt) {
if (!filter_var($rcpt, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException("Invalid recipient: {$rcpt}");
}
} Try / catch
try {
$mailer->send();
} catch (PHPMailer\PHPMailer\Exception $e) {
if (str_contains($mailer->ErrorInfo, 'recipients_failed')) {
error_log('Bad recipients: ' . $mailer->ErrorInfo); // lists address: error pairs
// prune failed addresses from list and requeue remaining
}
} Prevention
- Validate every recipient with FILTER_VALIDATE_EMAIL before addAddress().
- Scrub hard-bounced addresses from mailing lists regularly.
- Authenticate against the correct relay so external RCPT isn't relay-denied.
- Parse the exception message to recover per-recipient error codes.
When it happens
Trigger: Calling send() over SMTP when $this->smtp->recipient() returns false for any address during the RCPT TO loop: invalid/nonexistent recipient (550), relay denied (554), recipient over quota, or server rejecting due to rate/policy limits.
Common situations: Typo'd or bounce-hardened recipient addresses, sending to addresses that no longer exist, relaying denied for external recipients on an internal relay, distribution lists blocking external senders, per-recipient spam policies.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- $this->ErrorInfo
- $this->lang('data_not_accepted')
- $this->lang('instantiate')
- $this->lang('smtp_connect_failed')
- $message (getSmtpErrorMessage('connect_host'))
AI-assisted analysis of ellite/Wallos@52820e87ca (2026-09-13).
Data as JSON: /api/errors/00faff0086e5f6d4.
Report an issue: GitHub.
Appendix: source
Thrown at libs/PHPMailer/PHPMailer.php:2086
$this->doCallback(
$cb['issent'],
[[$cb['to'], $cb['name']]],
[],
[],
$this->Subject,
$body,
$this->From,
['smtp_transaction_id' => $smtp_transaction_id]
);
}
//Create error message for any bad addresses
if (count($bad_rcpt) > 0) {
$errstr = '';
foreach ($bad_rcpt as $bad) {
$errstr .= $bad['to'] . ': ' . $bad['error'];
}
throw new Exception($this->lang('recipients_failed') . $errstr, self::STOP_CONTINUE);
}
return true;
}
/**
* Initiate a connection to an SMTP server.
* Returns false if the operation failed.
*
* @param array $options An array of options compatible with stream_context_create()
*
* @throws Exception
*
* @uses \PHPMailer\PHPMailer\SMTP
*
* @return bool
*/
public function smtpConnect($options = null)View on GitHub (pinned to 52820e87ca)