phalcon/cphalcon · error · Phalcon\Auth\Exceptions\FileCannotRead
Stream adapter cannot read file: {path}
Error message
Stream adapter cannot read file: {path} What it means
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.
Source
Thrown at phalcon/Auth/Adapter/Stream.zep:79
*
* @phpstan-return list<AuthUserRow>
*
* @throws Exception
*/
protected function loadUsers() -> array
{
var contents, data, ex, path, rows;
let path = this->config->getFile();
if (!this->phpFileExists(path)) {
throw new FileDoesNotExist(path);
}
let contents = this->phpFileGetContents(path);
if (contents === false) {
throw new FileCannotRead(path);
}
try {
let data = (new Decode())->__invoke(contents, true);
} catch InvalidArgumentException, ex {
throw new FileNotValidJson(path, ex);
}
if (typeof data !== "array") {
throw new FileDoesNotContainJson(path);
}
/** @var list<AuthUserRow> $rows */
let rows = array_values(data);
return rows;
}
}View on GitHub (pinned to b7419de9cd)
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
Example fix
# before: file owned by root, php-fpm runs as www-data -rw------- 1 root root storage/users.json # after chown www-data:www-data storage/users.json chmod 640 storage/users.json
Defensive patterns
Strategy: validation
Validate before calling
$file = $config->getFile();
if (!is_readable($file)) {
throw new RuntimeException('Auth users file not readable by this process: ' . $file);
}
$adapter = new \Phalcon\Auth\Adapter\Stream($hasher, $config); Try / catch
try {
$guard->attempt($credentials);
} catch (\Phalcon\Auth\Exceptions\FileCannotRead $e) {
$logger->critical('Permissions problem on auth users file: ' . $e->getMessage());
throw new RuntimeException('Authentication store unavailable', 0, $e);
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Annotations directory cannot be written
- Stream adapter file does not exist: {path}
- Stream adapter file is not valid JSON: {path}
- Stream adapter file does not contain a JSON array: {path}
- Failed to write router cache temp file: {tmpPath}
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/c15d41563b05faf0.
Report an issue: GitHub.