{"record":{"id":"b8b5070d00f6c87a","repo":"passbolt/passbolt_api","slug":"no-openpgp-key-found-for-the-user-the-metadata-could-not-be","errorCode":null,"errorMessage":"No OpenPGP key found for the user. The metadata could not be encrypted with the user id: {0}.","messagePattern":"No OpenPGP key found for the user\\. The metadata could not be encrypted with the user id: (.+?)\\.","errorType":"exception","errorClass":"InternalErrorException","httpStatus":500,"severity":"error","filePath":"plugins/PassboltCe/Metadata/src/Service/Migration/MigrateAllV4FoldersToV5Service.php","lineNumber":158,"sourceCode":"     * @param \\Passbolt\\Folders\\Model\\Entity\\Folder $folder Folder entity.\n     * @return void\n     */\n    private function migratePersonal(MetadataFolderDto $dto, Folder $folder): void\n    {\n        $metadataArray = $dto->getClearTextMetadata();\n\n        /** @var \\App\\Model\\Entity\\Permission $permission */\n        $permission = $folder->get('permissions')[0];\n        $user = $permission->user;\n        if (is_null($user)) {\n            $msg = __('No user provided.') . ' ';\n            $msg .= __('The metadata could not be encrypted for permission id: {0}.', $permission->id);\n            throw new InternalErrorException($msg);\n        }\n        if (is_null($user->gpgkey)) {\n            $msg = __('No OpenPGP key found for the user.') . ' ';\n            $msg .= __('The metadata could not be encrypted with the user id: {0}.', $user->id);\n            throw new InternalErrorException($msg);\n        }\n\n        try {\n            $gpg = OpenPGPBackendFactory::get();\n            $gpg->clearKeys();\n            $gpg = $this->setSignKeyWithServerKey($gpg);\n            $gpg = $this->setEncryptKeyWithUserKey($gpg, $user->gpgkey);\n            $metadataClearText = json_encode($metadataArray, JSON_THROW_ON_ERROR);\n            $metadataEncrypted = $gpg->encrypt($metadataClearText, true);\n        } catch (Exception $exception) {\n            $msg = $exception->getMessage() . ' ';\n            $msg .= __('The metadata could not be encrypted with the user id: {0}.', $user->id);\n            throw new InternalErrorException($msg, 500, $exception);\n        }\n\n        $this->updateFolder($folder, [\n            'name' => null,\n            'metadata' => $metadataEncrypted,","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/Metadata/src/Service/Migration/MigrateAllV4FoldersToV5Service.php#L140-L176","documentation":"Continuation of migratePersonal's guards: the permission's user exists but has no GPG key (user->gpgkey is null), so the clear-text folder metadata cannot be encrypted. An InternalErrorException combining 'No OpenPGP key found for the user.' with the user ID is thrown.","triggerScenarios":"Migrating a personal folder owned by an active user who never uploaded an OpenPGP key, or whose gpgkeys row was deleted / contain('Gpgkeys') omitted from the query.","commonSituations":"Never-activated-but-active users without completed setup; key deletions during user cleanup; missing Gpgkeys contain() in the migration fetch.","solutions":["Have the affected user upload an OpenPGP key (or restore their key) before running the migration.","Exclude users without keys from migration targets and handle them separately.","Ensure the query contains Gpgkeys under Permissions.Users so existing keys are hydrated.","Pre-check with SQL: active users with folder permissions but no gpgkeys row."],"exampleFix":"// before\n$folders = $foldersTable->find()->contain(['Permissions.Users'])->all();\n// after\n$folders = $foldersTable->find()\n    ->contain(['Permissions.Users.Gpgkeys'])\n    ->innerJoinWith('Permissions.Users.Gpgkeys')\n    ->all();","handlingStrategy":"type-guard","validationCode":"$usersWithoutKeys = TableRegistry::getTableLocator()->get('Users')\n    ->find('activeNotDeleted')\n    ->innerJoinWith('Gpgkeys', function ($q) { return $q; })\n    ->notMatching('Gpgkeys')->all(); // or simply: users with folder permissions but no key","typeGuard":"if ($user === null || $user->gpgkey === null) {\n    continue; // cannot encrypt for this user\n}","tryCatchPattern":"try {\n    $service->migrate($uac);\n} catch (\\Cake\\Http\\Exception\\InternalErrorException $e) {\n    if (str_contains($e->getMessage(), 'No OpenPGP key found for the user.')) {\n        // have that user (id in message) upload a key, then retry\n    }\n}","preventionTips":["Contain Gpgkeys in the migration query so existing keys are loaded","Block folder migrations for users lacking OpenPGP keys, or generate/restore keys first","Run the passbolt healthcheck for missing user keys periodically"],"tags":["openpgp","encryption","migration","user-key"],"backgroundTag":"entity-not-found","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"}