BookStackApp/BookStack · error · LdapException
Provided path [{$caCertPath}] for LDAP TLS CA certs could no
Error message
Provided path [{$caCertPath}] for LDAP TLS CA certs could not be resolved to an existing location What it means
configureTlsCaCerts() validates the configured CA cert path with realpath(). If the path does not exist (or symlinks are broken), realpath() returns false and an LdapException is thrown before any LDAP connection is attempted. This is a configuration error surfaced early to fail fast.
Source
Thrown at app/Access/LdapService.php:289
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.
*
* @throws LdapException
*/
protected function configureTlsCaCerts(string $caCertPath): void
{
$errMessage = "Provided path [{$caCertPath}] for LDAP TLS CA certs could not be resolved to an existing location";
$path = realpath($caCertPath);
if ($path === false) {
throw new LdapException($errMessage);
}
if (is_dir($path)) {
$this->ldap->setOption(null, LDAP_OPT_X_TLS_CACERTDIR, $path);
} else if (is_file($path)) {
$this->ldap->setOption(null, LDAP_OPT_X_TLS_CACERTFILE, $path);
} else {
throw new LdapException($errMessage);
}
}
/**
* Parse an LDAP server string and return the host suitable for a connection.
* Is flexible to formats such as 'ldap.example.com:8069' or 'ldaps://ldap.example.com'.
*/
protected function parseServerString(string $serverString): string
{
if (str_starts_with($serverString, 'ldaps://') || str_starts_with($serverString, 'ldap://')) {View on GitHub (pinned to 18f8469a1c)
Solutions
- Verify the path exists: run realpath /path/to/certs on the server/container running the app
- Fix the LDAP_TLS_CA_CERT value in .env to an existing absolute path
- Mount or copy the CA bundle into the container if running in Docker/Kubernetes
- Ensure the web-server/PHP process user has permission to traverse the directory path
- Clear any config cache (php artisan config:clear) so the corrected value is picked up
Example fix
// before (.env) LDAP_TLS_CA_CERT=/etc/ssl/certs/ldap-ca.cr // after LDAP_TLS_CA_CERT=/etc/ssl/certs/ldap-ca.crt
Defensive patterns
Strategy: validation
Validate before calling
$caPath = config('services.ldap.tls_ca_cert');
if ($caPath && (realpath($caPath) === false)) {
throw new RuntimeException("LDAP TLS CA path does not exist: {$caPath}");
} Type guard
function isReadableCertPath(?string $path): bool {
return $path !== null && realpath($path) !== false && (is_dir($path) || is_file($path));
} Prevention
- Use absolute paths in .env, never relative ones
- In Docker, verify the CA file is mounted and readable by the PHP user
- Add a deployment health check that realpath's configured cert paths
- Run php artisan config:clear after changing cert paths
When it happens
Trigger: The LDAP TLS CA cert configuration value (LDAP_TLS_CA_CERT) points to a non-existent path; happens on every getConnection() call (via getUserWithAttributes, validateUserCredentials, getParentsOfGroup) while that config value is set.
Common situations: Typo in the .env path; container image without the CA file mounted; path valid on host but not inside Docker; typo'd or moved directory after upgrade; relative path resolved against unexpected working directory.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Could not start TLS connection. Further details in the appli
- Could not start TLS connection
- $exception->getMessage()
- Could not find or create a user for LDAP login.
- ($isAnonymous ? trans('errors.ldap_fail_anonymous') : trans(
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/102626390e431083.
Report an issue: GitHub.