ellite/Wallos · critical · Exception

$this->lang('smtp_connect_failed')

Error message

$this->lang('smtp_connect_failed')

What it means

smtpSend() throws this critical error when smtpConnect() fails to establish and initialize a session with the SMTP server (connect, EHLO, and optional STARTTLS all failed). The message is the localized 'SMTP connect() failed' string; details are usually in $mailer->SMTPDebug output or $mailer->ErrorInfo. No mail can be sent without a live SMTP session.

Solutions

  1. Enable $mailer->SMTPDebug = SMTP::DEBUG_SERVER; to see the exact connection/handshake failure.
  2. Verify Host and Port: telnet host port (or openssl s_client -connect host:port) from the same machine.
  3. Match encryption to server: SMTPSecure = ENCRYPTION_SMTPS with port 465, ENCRYPTION_STARTTLS with 587, or empty with 25.
  4. Confirm the openssl extension is loaded (php -m | grep openssl) for encrypted connections.
  5. Check firewall/provider blocks on the port and DNS resolution of the hostname.

Example fix

// before
$mailer->Host = 'smtp.gmail.com';
$mailer->Port = 25; // blocked/STARTTLS-only service
// after
$mailer->Host = 'smtp.gmail.com';
$mailer->SMTPAuth = true;
$mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mailer->Port = 587;
Defensive patterns

Strategy: retry

Validate before calling

$host = parse_url('tcp://' . $mailer->Host, PHP_URL_HOST);
if (@fsockopen($host, $mailer->Port, $errno, $errstr, 5) === false) {
    throw new RuntimeException("SMTP unreachable: {$host}:{$mailer->Port} ($errstr)");
}

Try / catch

try {
    $mailer->send();
} catch (PHPMailer\PHPMailer\Exception $e) {
    if (str_contains($mailer->ErrorInfo, 'SMTP connect() failed')) {
        error_log('SMTP connect failed: ' . $mailer->ErrorInfo . ' host=' . $mailer->Host . ':' . $mailer->Port);
        // retry with backoff or fall back to alternate transport
    }
}

Prevention

When it happens

Trigger: Calling send() with isSMTP() when $this->smtpConnect($this->SMTPOptions) returns false: wrong Host/port, firewall blocking outbound, server not offering expected encryption, or EHLO/STARTTLS negotiation failure on all hosts in the Host list.

Common situations: Typo'd SMTP host, port 25 blocked by cloud providers (AWS/GCP/DigitalOcean block it), missing PHP openssl extension for tls:// prefixes, DNS resolution failures, or trying STARTTLS against a server that only does implicit SSL.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of ellite/Wallos@52820e87ca (2026-09-13). Data as JSON: /api/errors/acf466e28e99c810. Report an issue: GitHub.

Appendix: source

Thrown at libs/PHPMailer/PHPMailer.php:2024

     * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
     *
     * @see PHPMailer::setSMTPInstance() to use a different class.
     *
     * @uses \PHPMailer\PHPMailer\SMTP
     *
     * @param string $header The message headers
     * @param string $body   The message body
     *
     * @throws Exception
     *
     * @return bool
     */
    protected function smtpSend($header, $body)
    {
        $header = static::stripTrailingWSP($header) . static::$LE . static::$LE;
        $bad_rcpt = [];
        if (!$this->smtpConnect($this->SMTPOptions)) {
            throw new Exception($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
        }
        //Sender already validated in preSend()
        if ('' === $this->Sender) {
            $smtp_from = $this->From;
        } else {
            $smtp_from = $this->Sender;
        }
        if (!$this->smtp->mail($smtp_from)) {
            $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
            throw new Exception($this->ErrorInfo, self::STOP_CRITICAL);
        }

        $callbacks = [];
        //Attempt to send to all recipients
        foreach ([$this->to, $this->cc, $this->bcc] as $togroup) {
            foreach ($togroup as $to) {
                if (!$this->smtp->recipient($to[0], $this->dsn)) {
                    $error = $this->smtp->getError();

View on GitHub (pinned to 52820e87ca)