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

The config for the server private key passphrase is invalid.

Error message

The config for the server private key passphrase is invalid.

What it means

assertServerPassphrase checks the configured server key passphrase is a string (empty string allowed). A non-string value (null, int from config) raises InternalErrorException since passphrase typing is a server-side config defect.

Solutions

  1. Define the passphrase as a string in config, e.g. 'passphrase' => (string)getenv('PASSBOLT_GPG_SERVER_KEY_PASSPHRASE')
  2. If the key has no passphrase, set it explicitly to empty string '' rather than leaving it undefined
  3. Quote the passphrase in passbolt.json/passbolt.php so numeric passphrases stay strings
  4. Run passbolt healthcheck to verify server key configuration

Example fix

// before
'passphrase' => getenv('PASSBOLT_GPG_SERVER_KEY_PASSPHRASE'), // null if unset
// after
'passphrase' => (string)(getenv('PASSBOLT_GPG_SERVER_KEY_PASSPHRASE') ?? ''),
Defensive patterns

Strategy: validation

Validate before calling

const pp = config.passbolt.gpg.serverKey.passphrase;
if (typeof pp !== 'string') throw new Error('server key passphrase must be a string (use "" if none)');

Type guard

function isStringPassphrase(v) { return typeof v === 'string'; }

Try / catch

try { await login(); } catch (e) { if (e.status === 500 && /passphrase is invalid/.test(e.message)) { fixPassphraseConfigType(); } }

Prevention

When it happens

Trigger: setServerKey bootstrap when passbolt.gpg.serverKey.passphrase is absent (null), set to a non-string type in passbolt.php, or an env-int interpolation yields a number instead of a string.

Common situations: Deployments where the passphrase env var is unset and config maps it directly (null); YAML/JSON config parsing '1234' as an integer; copy-pasted config omitting the passphrase key entirely.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltCe/JwtAuthentication/src/Authenticator/GpgJwtAuthenticator.php:375

     */
    public function assertServerFingerprint(mixed $fingerprint): void
    {
        if (!is_string($fingerprint) || !PublicKeyValidationService::isValidFingerprint($fingerprint)) {
            $msg = __('The config for the server private key fingerprint is not available or incomplete.');
            throw new InternalErrorException($msg);
        }
    }

    /**
     * @param mixed $passphrase passphrase
     * @throws \Cake\Http\Exception\InternalErrorException
     * @return void
     */
    public function assertServerPassphrase(mixed $passphrase): void
    {
        if (!is_string($passphrase)) {
            $msg = __('The config for the server private key passphrase is invalid.');
            throw new InternalErrorException($msg);
        }
    }

    /**
     * @param mixed $userId uuid
     * @throws \Cake\Http\Exception\BadRequestException
     * @return void
     */
    public function assertUserId(mixed $userId): void
    {
        if (!is_string($userId) || !Validation::uuid($userId)) {
            $msg = __('The user id is missing or invalid.');
            throw new BadRequestException($msg);
        }
    }

    /**
     * @param mixed $userData data

View on GitHub (pinned to 31c1bbc10f)