ellite/Wallos · critical · Exception

$this->lang('extension_missing') . 'openssl'

Error message

$this->lang('extension_missing') . 'openssl'

What it means

smtpConnect() throws this critical error when the connection requires encryption (SMTPSecure is STARTTLS or SMTPS, or the Host list implies tls/ssl) but the PHP OpenSSL extension is unavailable, detected by checking the OPENSSL_ALGO_SHA256 constant rather than extension_loaded(). The message is the localized 'extension missing' string plus 'openssl'. Without OpenSSL, encrypted SMTP cannot proceed at all.

Solutions

  1. Install/enable the OpenSSL extension: apt-get install php-openssl (usually bundled) or recompile PHP with --with-openssl.
  2. In Docker images, install e.g. apk add --no-cache libssl / use an image with openssl built in.
  3. Verify with php -m | grep openssl (and for the SAPI actually sending mail, check phpinfo()).
  4. If encryption genuinely can't be enabled, downgrade to an unencrypted local relay (SMTPSecure = '', port 25) only on trusted networks.
  5. Pin PHPMailer's requirement: add ext-openssl to composer.json so deployment fails fast on missing extension.

Example fix

// before (php.ini)
;extension=openssl
// after (php.ini)
extension=openssl
// then verify: php -m | grep openssl
Defensive patterns

Strategy: validation

Validate before calling

if ($mailer->SMTPSecure === PHPMailer::ENCRYPTION_STARTTLS || $mailer->SMTPSecure === PHPMailer::ENCRYPTION_SMTPS) {
    if (!defined('OPENSSL_ALGO_SHA256')) {
        throw new RuntimeException('ext-openssl required for encrypted SMTP');
    }
}

Try / catch

try {
    $mailer->send();
} catch (PHPMailer\PHPMailer\Exception $e) {
    if (str_contains($e->getMessage(), 'openssl')) {
        error_log('OpenSSL extension missing: enable ext-openssl in php.ini');
    }
}

Prevention

When it happens

Trigger: Calling send() with isSMTP() and $mailer->SMTPSecure = 'tls' or 'ssl' (or port implying it) while the PHP runtime lacks the openssl extension, e.g. a minimal PHP build without ext-openssl.

Common situations: Custom-compiled PHP without --with-openssl, stripped Alpine/Docker images, some shared hosting setups with openssl disabled, or PHP CLI vs web SAPI differences where only one has the extension.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at libs/PHPMailer/PHPMailer.php:2171

            }
            $prefix = '';
            $secure = $this->SMTPSecure;
            $tls = (static::ENCRYPTION_STARTTLS === $this->SMTPSecure);
            if ('ssl' === $hostinfo[1] || ('' === $hostinfo[1] && static::ENCRYPTION_SMTPS === $this->SMTPSecure)) {
                $prefix = 'ssl://';
                $tls = false; //Can't have SSL and TLS at the same time
                $secure = static::ENCRYPTION_SMTPS;
            } elseif ('tls' === $hostinfo[1]) {
                $tls = true;
                //TLS doesn't use a prefix
                $secure = static::ENCRYPTION_STARTTLS;
            }
            //Do we need the OpenSSL extension?
            $sslext = defined('OPENSSL_ALGO_SHA256');
            if (static::ENCRYPTION_STARTTLS === $secure || static::ENCRYPTION_SMTPS === $secure) {
                //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled
                if (!$sslext) {
                    throw new Exception($this->lang('extension_missing') . 'openssl', self::STOP_CRITICAL);
                }
            }
            $host = $hostinfo[2];
            $port = $this->Port;
            if (
                array_key_exists(3, $hostinfo) &&
                is_numeric($hostinfo[3]) &&
                $hostinfo[3] > 0 &&
                $hostinfo[3] < 65536
            ) {
                $port = (int) $hostinfo[3];
            }
            if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
                try {
                    if ($this->Helo) {
                        $hello = $this->Helo;
                    } else {
                        $hello = $this->serverHostname();

View on GitHub (pinned to 52820e87ca)