ellite/Wallos · error · Exception
$message (getSmtpErrorMessage('connect_host'))
Error message
$message (getSmtpErrorMessage('connect_host')) What it means
Thrown inside smtpConnect()'s host loop when STARTTLS negotiation fails: $this->smtp->startTLS() returns false after a plain connection with the server advertising STARTTLS. The message comes from getSmtpErrorMessage('connect_host') (typically 'SMTP connect() failed' plus debug info). Note the generic message can be misleading — the real cause is the TLS handshake, visible only with SMTPDebug.
Solutions
- Enable SMTPDebug = DEBUG_SERVER to see the actual TLS handshake error behind the generic message.
- Fix certificates: use a valid cert on the server or add its CA to the trust store / set $mailer->SMTPOptions['ssl']['cafile'].
- For dev/test relays only, relax verification: SMTPOptions = ['ssl' => ['verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true]].
- Update the system CA bundle (apt-get install ca-certificates / update-ca-certificates).
- If TLS is optional, disable it (SMTPSecure = '') only when the server genuinely permits plain sessions.
Example fix
// before (self-signed internal relay)
$mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // startTLS() fails
// after
$mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mailer->SMTPOptions = [
'ssl' => [
'verify_peer' => true,
'cafile' => '/etc/ssl/certs/internal-ca.pem', // trust the relay's CA
],
]; Defensive patterns
Strategy: try-catch
Validate before calling
$ctx = stream_context_create(['ssl' => ['capture_peer_cert' => true]]);
if (@stream_socket_client("tcp://{$mailer->Host}:{$mailer->Port}", $errno, $errstr, 5, STREAM_CLIENT_CONNECT, $ctx) === false) {
error_log("Pre-check: cannot reach {$mailer->Host}:{$mailer->Port}: $errstr");
}
// also confirm CA trust: openssl s_client -starttls smtp -connect host:port -CApath /etc/ssl/certs Try / catch
try {
$mailer->send();
} catch (PHPMailer\PHPMailer\Exception $e) {
if (str_contains($mailer->ErrorInfo, 'connect_host')) {
error_log('STARTTLS likely failed: rerun with SMTPDebug=DEBUG_SERVER for handshake detail');
// fix CA trust or relax SMTPOptions for trusted internal relays only
}
} Prevention
- Keep system CA bundles updated (ca-certificates).
- Use valid certificates on internal SMTP relays; add custom CAs via SMTPOptions['ssl']['cafile'].
- Restrict verify_peer=false to dev/test environments only.
- Enable SMTPDebug when a generic connect_host message hides a TLS failure.
When it happens
Trigger: Calling send() with isSMTP() when the server advertises STARTTLS but startTLS() fails: bad/mismatched certificates, untrusted self-signed cert, missing CA bundle (cafile not set), cipher mismatch, or server advertises TLS but is misconfigured.
Common situations: Self-signed or expired certificates on internal SMTP relays, missing/update ca-certificates package, localhost/test SMTP servers (MailHog) without valid certs, SMTPOptions ssl verify_peer settings blocking the handshake.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- $this->lang('smtp_connect_failed')
- $this->ErrorInfo
- $this->lang('data_not_accepted')
- $this->lang('recipients_failed') . $errstr
- ( )
AI-assisted analysis of ellite/Wallos@52820e87ca (2026-09-13).
Data as JSON: /api/errors/73c3ec093ba4f9b6.
Report an issue: GitHub.
Appendix: source
Thrown at libs/PHPMailer/PHPMailer.php:2210
//Automatically enable TLS encryption if:
//* it's not disabled
//* we are not connecting to localhost
//* we have openssl extension
//* we are not already using SSL
//* the server offers STARTTLS
if (
$this->SMTPAutoTLS &&
$this->Host !== 'localhost' &&
$sslext &&
$secure !== 'ssl' &&
$this->smtp->getServerExt('STARTTLS')
) {
$tls = true;
}
if ($tls) {
if (!$this->smtp->startTLS()) {
$message = $this->getSmtpErrorMessage('connect_host');
throw new Exception($message);
}
//We must resend EHLO after TLS negotiation
$this->smtp->hello($hello);
}
if (
$this->SMTPAuth && !$this->smtp->authenticate(
$this->Username,
$this->Password,
$this->AuthType,
$this->oauth
)
) {
throw new Exception($this->lang('authenticate'));
}
return true;
} catch (Exception $exc) {
$lastexception = $exc;View on GitHub (pinned to 52820e87ca)