{"record":{"id":"f3c50086b97927ba","repo":"passbolt/passbolt_api","slug":"could-not-read-the-file-0","errorCode":null,"errorMessage":"Could not read the file: {0}","messagePattern":"Could not read the file: (.+?)","errorType":"console","errorClass":"CakeException","httpStatus":null,"severity":"error","filePath":"src/Command/KeyringInitCommand.php","lineNumber":68,"sourceCode":"\n    /**\n     * @inheritDoc\n     */\n    public function execute(Arguments $args, ConsoleIo $io): ?int\n    {\n        parent::execute($args, $io);\n\n        // Root user is not allowed to execute this command.\n        $this->assertCurrentProcessUser($io, $this->processUserService);\n\n        try {\n            $filePath = Configure::read('passbolt.gpg.serverKey.private');\n            if (!file_exists($filePath)) {\n                throw new CakeException(__('The file does not exist: {0}', $filePath));\n            }\n            $armoredKey = file_get_contents($filePath);\n            if ($armoredKey === false) {\n                throw new CakeException(__('Could not read the file: {0}', $filePath));\n            }\n            // Import the private key in the OpenPGP keyring\n            $gpg = OpenPGPBackendFactory::get();\n\n            $io->out('Importing ' . $filePath);\n            $gpg->importKeyIntoKeyring($armoredKey);\n        } catch (CakeException $e) {\n            $this->error($e->getMessage(), $io);\n            $this->error('Could not import the server OpenPGP key into the keyring.', $io);\n\n            return $this->errorCode();\n        }\n\n        $this->success('Keyring init OK', $io);\n\n        return $this->successCode();\n    }\n}","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Command/KeyringInitCommand.php#L50-L86","documentation":"In KeyringInitCommand, after confirming the private key file exists, file_get_contents() returns false (PHP warning suppressed by @ or checked here) when the file cannot be read — typically due to filesystem permissions, unreadable ownership, or an I/O problem. The command throws because it cannot import a key it cannot read.","triggerScenarios":"file_exists() passes but file_get_contents() fails on passbolt.gpg.serverKey.private: file owned by root with mode 600 while command runs as www-data, directory without execute permission, SELinux/AppArmor denial, or the path is a directory/special file.","commonSituations":"Key generated as root then command run as www-data (or vice versa); Docker image where key is mounted root-owned 600; SELinux enforcing on RHEL/Fedora; NFS/permissions issues after restore.","solutions":["Fix ownership/permissions: chown www-data:www-data <keyfile> && chmod 600 <keyfile>, then re-run keyring init as the web server user.","Run the command as the same user that owns the key: sudo su -s /bin/bash -c './bin/cake passbolt keyring init' www-data.","Check the path is a regular file (ls -l) and the parent directories grant +x traversal.","If SELinux denies access, restore correct context (restorecon) or check audit logs (ausearch -m avc)."],"exampleFix":"// before: root-owned key, command runs as www-data -> read fails\n-rw------- root root /etc/passbolt/serverkey_private.asc\n// after\n$ chown www-data:www-data /etc/passbolt/serverkey_private.asc && chmod 600 /etc/passbolt/serverkey_private.asc\n$ sudo su -s /bin/bash -c './bin/cake passbolt keyring init' www-data","handlingStrategy":"type-guard","validationCode":"$path = Configure::read('passbolt.gpg.serverKey.private');\nif (!is_file($path) || !is_readable($path)) {\n    fwrite(STDERR, \"Cannot read key file '{$path}' as user \" . get_current_user() . \". Check owner/permissions.\\n\");\n    exit(1);\n}","typeGuard":null,"tryCatchPattern":"try {\n    $this->KeyringInitCommand->execute($args, $io);\n} catch (CakeException $e) {\n    if (str_starts_with($e->getMessage(), 'Could not read the file')) {\n        // chown/chmod the key for the current user, or re-run as its owner\n    }\n}","preventionTips":["Always run passbolt CLI commands as the web server user (www-data).","Keep server key owned by www-data with mode 600 and traversable parent dirs.","Check SELinux/AppArmor policies when access looks correct but still fails.","Re-apply ownership after restoring or copying key files."],"tags":["cli","gpg","permissions","filesystem"],"backgroundTag":"file-read-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"}