passbolt/passbolt_api · critical · Cake\Http\Exception\InternalErrorException
The OpenPGP server key defined in the config cannot be…
Error message
The OpenPGP server key defined in the config cannot be opened.
What it means
After confirming the configured private key file exists, importServerKeyInKeyring reads it with file_get_contents(). If that returns false (the file exists but cannot be read/opened by the process), this InternalErrorException is thrown. It signals a filesystem-level read failure rather than a missing or malformed key.
Solutions
- Chown/chmod the key file so the web server user can read it: `chown www-data:www-data <keyfile> && chmod 0400 <keyfile>`.
- Check `ls -l` on the file and each parent directory for execute/read permission for the PHP user.
- If open_basedir is set, add the key's directory to it in php.ini and restart PHP-FPM/Apache.
- Verify the path is a regular file (`file <keyfile>`), not a directory or broken symlink target.
Example fix
// before -rw------- root root /etc/passbolt/serverkey_private.asc // after chown www-data:www-data /etc/passbolt/serverkey_private.asc && chmod 0400 /etc/passbolt/serverkey_private.asc
Defensive patterns
Strategy: validation
Validate before calling
$keyPath = Configure::read('passbolt.gpg.serverKey.private');
if (!is_readable($keyPath)) {
throw new \RuntimeException("Server key exists but is not readable by user " . get_current_user());
} Try / catch
try {
$backend->importServerKeyInKeyring($fingerprint, $keyPath);
} catch (\Cake\Http\Exception\InternalErrorException $e) {
if (str_contains($e->getMessage(), 'cannot be opened')) {
clearstatcache(true, $keyPath); // diagnose permissions before retry
}
throw $e;
} Prevention
- Standardize key file ownership (www-data) and mode 0400 in provisioning scripts.
- Test readability as the PHP user during deploy: `sudo -u www-data test -r <keyfile>`.
- Keep key directory out of open_basedir restrictions or explicitly whitelist it.
When it happens
Trigger: file_get_contents($keyFilePath) === false during importServerKeyInKeyring: permission denied on the file, unreadable directory, open_basedir restriction, or the path is a directory/unreadable special file.
Common situations: Key file owned by root with 0600 while PHP runs as www-data; restrictive SELinux/AppArmor policy; open_basedir in php.ini excluding the key path; Docker volume mounted with wrong ownership.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- The OpenPGP public key file '$publicKeyFileName' is not…
- The OpenPGP server key defined in the config cannot be used…
- The OpenPGP server key defined in the config cannot be used…
- The OpenPGP server key defined in the config cannot be used…
- The OpenPGP server key defined in the config cannot be used…
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/501331edfa7b78e7.
Report an issue: GitHub.
Appendix: source
Thrown at src/Utility/OpenPGP/OpenPGPBackend.php:101
*/
public function importServerKeyInKeyring(): void
{
$fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint');
$keyFilePath = Configure::read('passbolt.gpg.serverKey.private');
// If it's not in keyring try to import it
// Check if file containing the private key exist
if ($keyFilePath === null) {
throw new InternalErrorException('The secret key file is not defined.');
}
if (!file_exists($keyFilePath)) {
$msg = __('The OpenPGP server key defined in the config is not found in the file system.');
throw new InternalErrorException($msg);
}
$privateKey = file_get_contents($keyFilePath);
if ($privateKey === false) {
$msg = __('The OpenPGP server key defined in the config cannot be opened.');
throw new InternalErrorException($msg);
}
if (!$this->isParsableArmoredPrivateKey($privateKey)) {
$msg = __('The OpenPGP server key defined on file is not a valid private key.');
throw new InternalErrorException($msg);
}
// try to import it
$this->importKeyIntoKeyring($privateKey);
if (!$this->isKeyInKeyring($fingerprint)) {
$msg = __('There is an issue with the OpenPGP server key.') . ' ';
$msg .= __('The fingerprint does not match the one associated with the key on file.');
throw new InternalErrorException($msg);
}
}
/**
* Check if a message is valid.
*View on GitHub (pinned to 31c1bbc10f)