{"record":{"id":"c15d41563b05faf0","repo":"phalcon/cphalcon","slug":"stream-adapter-cannot-read-file-path","errorCode":null,"errorMessage":"Stream adapter cannot read file: {path}","messagePattern":"Stream adapter cannot read file: (.+?)","errorType":"exception","errorClass":"Phalcon\\Auth\\Exceptions\\FileCannotRead","httpStatus":null,"severity":"error","filePath":"phalcon/Auth/Adapter/Stream.zep","lineNumber":79,"sourceCode":"     *\n     * @phpstan-return list<AuthUserRow>\n     *\n     * @throws Exception\n     */\n    protected function loadUsers() -> array\n    {\n        var contents, data, ex, path, rows;\n\n        let path = this->config->getFile();\n\n        if (!this->phpFileExists(path)) {\n            throw new FileDoesNotExist(path);\n        }\n\n        let contents = this->phpFileGetContents(path);\n\n        if (contents === false) {\n            throw new FileCannotRead(path);\n        }\n\n        try {\n            let data = (new Decode())->__invoke(contents, true);\n        } catch InvalidArgumentException, ex {\n            throw new FileNotValidJson(path, ex);\n        }\n\n        if (typeof data !== \"array\") {\n            throw new FileDoesNotContainJson(path);\n        }\n\n        /** @var list<AuthUserRow> $rows */\n        let rows = array_values(data);\n\n        return rows;\n    }\n}","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Auth/Adapter/Stream.zep#L61-L97","documentation":"After confirming the users file exists, the Auth Stream adapter reads it with file_get_contents; a false return (not mere emptiness) means the OS refused the read, and the adapter reports FileCannotRead with the path. This is an environment/permission problem, not a content problem — JSON validity is checked later.","triggerScenarios":"Authenticating via the Stream adapter where the file exists but is unreadable by the PHP process: wrong owner/mode, open_basedir excluding the directory, SELinux denial, or a dangling symlink.","commonSituations":"Files created by root/deploy user while php-fpm runs as www-data; hardened shared hosting with open_basedir; container images with restrictive umasks; symlink to a protected location.","solutions":["Grant read access: `chown www-data:www-data storage/users.json` or `chmod 640` with proper group","Verify with `sudo -u www-data cat <path>` to reproduce the exact denial","Check open_basedir/SELinux (`getenforce`, audit log) and allow the directory"],"exampleFix":"# before: file owned by root, php-fpm runs as www-data\n-rw------- 1 root root storage/users.json\n# after\nchown www-data:www-data storage/users.json\nchmod 640 storage/users.json","handlingStrategy":"validation","validationCode":"$file = $config->getFile();\nif (!is_readable($file)) {\n    throw new RuntimeException('Auth users file not readable by this process: ' . $file);\n}\n$adapter = new \\Phalcon\\Auth\\Adapter\\Stream($hasher, $config);","typeGuard":null,"tryCatchPattern":"try {\n    $guard->attempt($credentials);\n} catch (\\Phalcon\\Auth\\Exceptions\\FileCannotRead $e) {\n    $logger->critical('Permissions problem on auth users file: ' . $e->getMessage());\n    throw new RuntimeException('Authentication store unavailable', 0, $e);\n}","preventionTips":["Ship config/data files with explicit ownership for the PHP user (e.g. www-data) in provisioning","Run `sudo -u <php-user> cat <file>` during setup to verify read access","Include a readability check for required files in deployment smoke tests"],"tags":["auth","stream-adapter","permissions","filesystem"],"backgroundTag":"file-permission-denied","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}