{"record":{"id":"b5925d6d0c79f829","repo":"passbolt/passbolt_api","slug":"exceptionmessage-the-metadata-could-not-be-encrypted-with-b5925d","errorCode":null,"errorMessage":"{exceptionMessage} The metadata could not be encrypted with the metadata key id: {0}.","messagePattern":"(.+?) The metadata could not be encrypted with the metadata key id: (.+?)\\.","errorType":"exception","errorClass":"InternalErrorException","httpStatus":500,"severity":"error","filePath":"plugins/PassboltCe/Metadata/src/Service/Migration/MigrateAllV4FoldersToV5Service.php","lineNumber":203,"sourceCode":"     * @return void\n     * @throws \\Cake\\Datasource\\Exception\\RecordNotFoundException When there is no metadata key record.\n     */\n    private function migrateShared(MetadataFolderDto $dto, Folder $folder): void\n    {\n        $metadataArray = $dto->getClearTextMetadata();\n        $metadataKey = $this->getMetadataKeyForEncryption();\n\n        try {\n            $gpg = OpenPGPBackendFactory::get();\n            $gpg->clearKeys();\n            $gpg = $this->setSignKeyWithServerKey($gpg);\n            $gpg = $this->setEncryptKeyWithMetadataKey($gpg, $metadataKey);\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 metadata key id: {0}.', $metadataKey->id);\n            throw new InternalErrorException($msg, 500, $exception);\n        }\n\n        $this->updateFolder($folder, [\n            'name' => null,\n            'metadata' => $metadataEncrypted,\n            'metadata_key_id' => $metadataKey->id,\n            'metadata_key_type' => 'shared_key',\n            //TODO support nullable resource.modified_by to allow server side modification\n            //'modified_by' => null,\n        ]);\n    }\n\n    /**\n     * Updates entity with given data.\n     *\n     * @param \\Passbolt\\Folders\\Model\\Entity\\Folder $folder Folder entity to update.\n     * @param array $data Data to update.\n     * @return void","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/Metadata/src/Service/Migration/MigrateAllV4FoldersToV5Service.php#L185-L221","documentation":"Shared-folder migration encrypts metadata with the active metadata (shared) key; any exception from backend setup, metadata key loading, JSON encoding, or gpg->encrypt() is re-thrown as InternalErrorException prefixed with the original message and suffixed with the metadata key ID, chaining the original exception.","triggerScenarios":"Calling migrate → migrateShared when encryption with the metadata key fails: key material/fingerprint invalid or missing from keyring, key expired/revoked, gpg binary issues, or JSON_THROW_ON_ERROR firing while encoding the metadata array.","commonSituations":"Metadata key deleted from keyring but row still active; mismatched armored key data in DB; wrong GNUPGHOME; folder names with invalid UTF-8 breaking json_encode.","solutions":["Inspect the prefixed exceptionMessage / chained exception to find the root GPG error.","Verify the metadata key is active, not expired/revoked, and its armored public key imports cleanly into the keyring.","Check GNUPGHOME configuration and permissions for the PHP process, and that setEncryptKeyWithMetadataKey succeeded.","Validate the metadata payload is UTF-8 clean before json_encode, or sanitize folder names first."],"exampleFix":"// before\n$metadataClearText = json_encode($metadataArray, JSON_THROW_ON_ERROR);\n$metadataEncrypted = $gpg->encrypt($metadataClearText, true);\n// after: guard encoding and key import\n$metadataClearText = json_encode(\n    $this->sanitizeUtf8($metadataArray),\n    JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE\n);\nif (!$metadataKey->expired && !$metadataKey->deleted) {\n    $metadataEncrypted = $gpg->encrypt($metadataClearText, true);\n}","handlingStrategy":"try-catch","validationCode":"// preflight: metadata key active and importable\n$gpg = OpenPGPBackendFactory::get();\n$gpg->clearKeys();\n$gpg->importKeyIntoKeyring($metadataKey->armored_key);\n$gpg->encrypt('test', true); // smoke-test encryption with the metadata key","typeGuard":null,"tryCatchPattern":"try {\n    $service->migrate($uac);\n} catch (\\Cake\\Http\\Exception\\InternalErrorException $e) {\n    error_log($e->getPrevious()?->getMessage() ?? $e->getMessage());\n    // re-import/rotate the metadata key identified in the message, then retry\n}","preventionTips":["Smoke-test encryption with the active metadata key before batch migration","Rotate metadata keys before expiry and keep the keyring in sync with the DB","Ensure folder names are valid UTF-8 to avoid json_encode (JSON_THROW_ON_ERROR) failures","Confirm GNUPGHOME configuration for the process running the migration"],"tags":["openpgp","encryption","metadata-key","migration"],"backgroundTag":"http-request-failed","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"}