BookStackApp/BookStack · error · LdapException

Could not start TLS connection. Further details in the appli

Error message

Could not start TLS connection. Further details in the application log.

What it means

LdapService::getConnection calls startTls() on an LDAP connection to upgrade a plaintext ldap:// connection to TLS. When the PHP LDAP wrapper's startTls() throws (or the underlying ldap_start_tls() fails), the service logs the LDAP error string and the diagnostic message, then throws this generic LdapException because the specific cause (certificate failure, protocol mismatch, etc.) is only in the application log.

Source

Thrown at app/Access/LdapService.php:262

        if ($ldapConnection === false) {
            throw new LdapException(trans('errors.ldap_cannot_connect'));
        }

        // Set any required options
        if ($this->config['version']) {
            $this->ldap->setVersion($ldapConnection, $this->config['version']);
        }

        // Start and verify TLS if it's enabled
        if ($this->config['start_tls']) {
            try {
                $started = $this->ldap->startTls($ldapConnection);
            } catch (\Exception $exception) {
                $error = $exception->getMessage() . ' :: ' . ldap_error($ldapConnection);
                ldap_get_option($ldapConnection, LDAP_OPT_DIAGNOSTIC_MESSAGE, $detail);
                Log::info("LDAP STARTTLS failure: {$error} {$detail}");
                throw new LdapException('Could not start TLS connection. Further details in the application log.');
            }
            if (!$started) {
                throw new LdapException('Could not start TLS connection');
            }
        }

        $this->ldapConnection = $ldapConnection;

        return $this->ldapConnection;
    }

    /**
     * Configure TLS CA certs globally for ldap use.
     * This will detect if the given path is a directory or file, and set the relevant
     * LDAP TLS options appropriately otherwise throw an exception if no file/folder found.
     *
     * Note: When using a folder, certificates are expected to be correctly named by hash
     * which can be done via the c_rehash utility.

View on GitHub (pinned to 18f8469a1c)

Solutions

  1. Check the application log for the 'LDAP STARTTLS failure:' entry which contains the raw ldap_error and diagnostic message
  2. Verify the LDAP server supports STARTTLS (ldapsearch -ZZ -H ldap://host) and that it is enabled server-side
  3. Set the correct CA cert file/directory via the LDAP TLS CA cert config option, or set LDAPTLS_REQCERT=never only for testing
  4. Ensure the certificate hostname matches the LDAP host you connect to and the cert is not expired
  5. If TLS is unnecessary in your environment, disable the start_tls option so connections use ldaps:// or plaintext

Example fix

// before (php.ini / env)
; LDAPTLS_CACERT not set, self-signed cert rejected
// after
LDAPTLS_CACERT=/etc/ssl/certs/ldap-ca.pem
// or in BookStack .env
LDAP_START_TLS=true
LDAP_TLS_CA_CERT=/etc/ssl/certs/ldap-ca.pem
Defensive patterns

Strategy: try-catch

Validate before calling

// before connecting, verify the LDAP endpoint supports STARTTLS
$ok = ($fp = @fsockopen($host, 389, $errno, $errstr, 5)) && stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT) !== false;
if ($fp) fclose($fp);
if (!$ok) { /* abort: STARTTLS unavailable */ }

Try / catch

try {
    $conn = $ldapService->getUserWithAttributes($userName, $attrs);
} catch (LdapException $e) {
    Log::error('LDAP STARTTLS failed', ['msg' => $e->getMessage(),
        'app_log' => 'see LDAP STARTTLS failure entry for diagnostics']);
    // fall back to ldaps:// or show a config error page
}

Prevention

When it happens

Trigger: Calling getUserWithAttributes, validateUserCredentials, or getParentsOfGroup triggers getConnection, which invokes startTls() against an ldap:// server that fails the TLS handshake: untrusted/self-signed CA cert, wrong CA bundle path, hostname mismatch, server not supporting STARTTLS, or TLS protocol version mismatch.

Common situations: LDAP server configured without TLS support while 'start_tls' is enabled in BookStack config; corporate proxy stripping STARTTLS; expired or self-signed certificates; missing/incorrect LDAP_TLS_CA_CERT path; OpenLDAP client compiled against a TLS library that rejects the server's ciphers.

Understand the failure class

Related errors


AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02). Data as JSON: /api/errors/85dd7f6b96c8c8e5. Report an issue: GitHub.