passbolt/passbolt_api · critical · Cake\Http\Exception\InternalErrorException

The OpenPGP server key defined in the config is not found…

Error message

The OpenPGP server key defined in the config is not found in the file system.

What it means

importServerKeyInKeyring loads the server's OpenPGP private key from the file path given in config and imports it into the GnuPG keyring. Before reading the file it checks file_exists($keyFilePath); when the path is null-adjacent misconfiguration resolves to a path that does not exist on disk, this InternalErrorException is thrown. It means the configured secret key file is absent from the filesystem.

Solutions

  1. Verify the config value passbolt.gpg.serverKey.private (or PASSBOLT_GPG_SERVER_KEY_PRIVATE env var) points to an existing absolute path.
  2. Create or restore the server key: run `su -s /bin/bash -c "gpg --home /var/lib/passbolt --gen-key" www-data` or copy the existing key file to the configured location.
  3. Ensure the web server user (www-data) can read the file and the containing directory (check permissions/SELinux).
  4. In containerized deployments, confirm the key file is present inside the container/volume, not only on the host.

Example fix

// before (config/passbolt.php)
'serverKey' => ['private' => '/config/gpg/serverkey_private.asc'], // file missing
// after: place the key there and confirm
is_file('/config/gpg/serverkey_private.asc') || throw new \RuntimeException('mount the server private key at /config/gpg/serverkey_private.asc');
Defensive patterns

Strategy: validation

Validate before calling

$keyPath = Configure::read('passbolt.gpg.serverKey.private');
if (!is_string($keyPath) || !is_file($keyPath)) {
    throw new \RuntimeException("Server private key not found at: " . var_export($keyPath, true));
}

Try / catch

try {
    $backend->importServerKeyInKeyring($fingerprint, $keyPath);
} catch (\Cake\Http\Exception\InternalErrorException $e) {
    if (str_contains($e->getMessage(), 'not found in the file system')) {
        // log config path, alert operator
    }
    throw $e;
}

Prevention

When it happens

Trigger: Calling importServerKeyInKeyring() when the configured PASSBOLT_GPG_SERVER_KEY_PRIVATE path points to a file that does not exist (file_exists() returns false).

Common situations: Fresh installs where passbolt.php or environment variables were never pointed at a key file; the key was generated on another host and never copied; Docker volume not mounted; wrong relative vs absolute path; key deleted during cleanup.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/52349f46a919af95. Report an issue: GitHub.

Appendix: source

Thrown at src/Utility/OpenPGP/OpenPGPBackend.php:96

    /**
     * Import server key in keyring
     *
     * @throws \Cake\Http\Exception\InternalErrorException if server key is undefined or invalid
     * @return void
     */
    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);
        }

View on GitHub (pinned to 31c1bbc10f)