{"record":{"id":"117b6a489021bbcb","repo":"passbolt/passbolt_api","slug":"the-user-public-key-is-not-available-or-incomplete","errorCode":null,"errorMessage":"The user public key is not available or incomplete.","messagePattern":"The user public key is not available or incomplete\\.","errorType":"http","errorClass":"InternalErrorException","httpStatus":500,"severity":"error","filePath":"src/Service/OpenPGP/OpenPGPCommonUserOperationsTrait.php","lineNumber":109,"sourceCode":"                }\n                $msg = __('Could not import the user OpenPGP key.');\n                throw new InternalErrorException($msg, 500, $exception);\n            }\n        }\n\n        return $gpg;\n    }\n\n    /**\n     * @param \\App\\Model\\Entity\\Gpgkey $userKey object as sent from event\n     * @return void\n     * @throws \\Cake\\Http\\Exception\\InternalErrorException if the user key cannot be loaded\n     */\n    private function assertUserKey(Gpgkey $userKey): void\n    {\n        if (!isset($userKey->armored_key) || !isset($userKey->fingerprint)) {\n            $msg = __('The user public key is not available or incomplete.');\n            throw new InternalErrorException($msg);\n        }\n\n        $fingerprint = $userKey->fingerprint;\n        if (!is_string($fingerprint) || !PublicKeyValidationService::isValidFingerprint($fingerprint)) {\n            $msg = __('The user public key fingerprint is not available or incomplete.');\n            throw new InternalErrorException($msg);\n        }\n\n        $armoredKey = $userKey->armored_key;\n        if (!is_string($armoredKey) || !PublicKeyValidationService::parseAndValidatePublicKey($armoredKey)) {\n            $msg = __('The user armored key is not available or incomplete.');\n            throw new InternalErrorException($msg);\n        }\n    }\n}\n","sourceCodeStart":91,"sourceCodeEnd":125,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Service/OpenPGP/OpenPGPCommonUserOperationsTrait.php#L91-L125","documentation":"InternalErrorException thrown by OpenPGPCommonUserOperationsTrait::assertUserKey when a Gpgkey entity is missing either its armored_key or fingerprint field. The trait uses this guard before configuring the OpenPGP backend with a user key for encryption or verification, since both fields are mandatory to use the key.","triggerScenarios":"Calling setEncryptKeyWithUserKey($userKey) or setVerifyKeyWithUserKey($userKey) with a Gpgkey entity whose armored_key or fingerprint property is null/unset (e.g. entity built with select() omitting those columns, or a partially hydrated entity).","commonSituations":"Fetching user Gpgkey rows with a fields/select list that excludes armored_key or fingerprint; using a Gpgkey entity constructed manually with only partial data; data corruption or incomplete key import in gpgkeys table.","solutions":["Ensure the Gpgkey entity passed to setEncryptKeyWithUserKey/setVerifyKeyWithUserKey contains both armored_key and fingerprint (check the table query's select/contain).","If the key is genuinely missing, verify the user completed the OpenPGP key setup (gpgkeys record exists and is complete) before invoking encrypted operations.","Catch InternalErrorException and surface a meaningful message instead of leaking a 500 to the client.","Inspect the gpgkeys table row for the user to confirm armored_key and fingerprint are populated."],"exampleFix":"// before\n$userKey = $this->Gpgkeys->find()->where(['user_id' => $userId])->select(['id', 'fingerprint'])->first();\n$gpg->setEncryptKeyWithUserKey($userKey);\n\n// after\n$userKey = $this->Gpgkeys->find()->where(['user_id' => $userId])->first(); // full entity, includes armored_key\nif ($userKey === null || !is_string($userKey->armored_key) || !is_string($userKey->fingerprint)) {\n    throw new UserNotFoundException(__('No valid OpenPGP key for this user.'));\n}\n$gpg->setEncryptKeyWithUserKey($userKey);","handlingStrategy":"validation","validationCode":"// PHP\nif (!isset($userKey->armored_key) || !isset($userKey->fingerprint)) {\n    throw new BadRequestException(__('User OpenPGP key data is incomplete.'));\n}\n$gpg->setEncryptKeyWithUserKey($userKey);","typeGuard":"function isCompleteUserKey(\\Passbolt\\WebInstaller\\...\\Gpgkey $k): bool {\n    return isset($k->armored_key) && isset($k->fingerprint);\n}","tryCatchPattern":"try {\n    $gpg->setEncryptKeyWithUserKey($userKey);\n} catch (\\Cake\\Http\\Exception\\InternalErrorException $e) {\n    $this->log($e->getMessage());\n    throw new BadRequestException(__('This user has no usable OpenPGP key.'));\n}","preventionTips":["Always load full Gpgkey entities; avoid select() that drops armored_key or fingerprint.","Assert key completeness in a shared guard before any OpenPGP operation.","Add a data health check that reports gpgkeys rows missing armored_key/fingerprint."],"tags":["openpgp","gpg","missing-data","internal-error"],"backgroundTag":"empty-required-field","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}