ellite/Wallos · critical · Exception
$this->lang('execute') . $this->Sendmail
Error message
$this->lang('execute') . $this->Sendmail What it means
sendmailSend() (Sendmail transport, called from postSend) throws the localized 'execute' text plus $this->Sendmail with STOP_CRITICAL when @popen($sendmail, 'w') fails while $SingleTo is enabled — i.e., PHP could not start the sendmail binary process to write the message to.
Solutions
- Verify the sendmail binary exists and is executable at $mail->Sendmail (default /usr/sbin/sendmail -t -i); adjust $mail->Sendmail accordingly
- Install a sendmail-compatible MTA (postfix, msmtp) in the environment, or switch to SMTP: $mail->isSMTP() with host/auth settings
- Check open_basedir/safe_mode and OS-level restrictions that block popen
- Log the Sendmail path and test it manually: echo test | /usr/sbin/sendmail -t -i
Example fix
// before
$mail->isSendmail();
$mail->Sendmail = '/usr/sbin/sendmail'; // binary missing
// after
if (!is_executable('/usr/sbin/sendmail')) {
$mail->isSMTP();
$mail->Host = 'smtp.example.com';
$mail->SMTPAuth = true;
$mail->Username = '...';
$mail->Password = '...';
} else {
$mail->isSendmail();
} Defensive patterns
Strategy: try-catch
Validate before calling
$cmd = explode(' ', $mail->Sendmail)[0]; if (!is_executable($cmd)) { throw new RuntimeException("Sendmail binary not executable: $cmd"); } Try / catch
try { $mail->send(); } catch (PHPMailer\PHPMailer\Exception $e) { if (str_contains($e->getMessage(), 'execute')) { log_mta_failure($e->getMessage()); fallback_to_smtp($mail); } else { throw $e; } } Prevention
- Verify the Sendmail path at deployment time (is_executable check)
- Install an MTA (postfix/msmtp) in containers/images that use isSendmail()
- Prefer SMTP transport in cloud/container environments
- Watch for open_basedir/disable_functions restrictions on popen
When it happens
Trigger: $mail->isSendmail() with $mail->SingleTo=true; popen fails because the Sendmail path ($mail->Sendmail, default /usr/sbin/sendmail) does not exist or is not executable, safe_mode/open_basedir restrictions, or process/fork limits.
Common situations: Local dev machines without a sendmail-compatible MTA installed, misconfigured Sendmail path (e.g., pointing to msmtp that is not installed), containers stripped of sendmail, PHP deployed without permission to execute binaries.
Related errors
AI-assisted analysis of ellite/Wallos@52820e87ca (2026-09-13).
Data as JSON: /api/errors/097489b188fb43dd.
Report an issue: GitHub.
Appendix: source
Thrown at libs/PHPMailer/PHPMailer.php:1767
//allow sendmail to choose a default envelope sender. It may
//seem preferable to force it to use the From header as with
//SMTP, but that introduces new problems (see
//<https://github.com/PHPMailer/PHPMailer/issues/2298>), and
//it has historically worked this way.
$sendmailFmt = '%s -oi -t';
}
$sendmail = sprintf($sendmailFmt, escapeshellcmd($this->Sendmail), $this->Sender);
$this->edebug('Sendmail path: ' . $this->Sendmail);
$this->edebug('Sendmail command: ' . $sendmail);
$this->edebug('Envelope sender: ' . $this->Sender);
$this->edebug("Headers: {$header}");
if ($this->SingleTo) {
foreach ($this->SingleToArray as $toAddr) {
$mail = @popen($sendmail, 'w');
if (!$mail) {
throw new Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
}
$this->edebug("To: {$toAddr}");
fwrite($mail, 'To: ' . $toAddr . "\n");
fwrite($mail, $header);
fwrite($mail, $body);
$result = pclose($mail);
$addrinfo = static::parseAddresses($toAddr, true, $this->CharSet);
$this->doCallback(
($result === 0),
[[$addrinfo['address'], $addrinfo['name']]],
$this->cc,
$this->bcc,
$this->Subject,
$body,
$this->From,
[]
);
$this->edebug("Result: " . ($result === 0 ? 'true' : 'false'));View on GitHub (pinned to 52820e87ca)