phacility/phabricator · critical · PhutilProxyException
Configuration file "%s" exists, but could not be read.
Error message
Configuration file "%s" exists, but could not be read.
What it means
PhabricatorConfigLocalSource loads conf/local/local.json, the instance-local configuration override file. If the path exists but Filesystem::readFile() throws (unreadable permissions, removed mid-read, path is a directory, safe-mode restriction), the FilesystemException is wrapped in PhutilProxyException with this message and every config read that needs the local source fails. This is a boot-level failure: the local source participates in config stack construction, so the web UI and CLI both break until it is fixed.
Source
Thrown at src/infrastructure/env/PhabricatorConfigLocalSource.php:32
}
public function deleteKeys(array $keys) {
$result = parent::deleteKeys($keys);
$this->saveConfig();
return parent::deleteKeys($keys);
}
private function loadConfig() {
$path = $this->getConfigPath();
if (!Filesystem::pathExists($path)) {
return array();
}
try {
$data = Filesystem::readFile($path);
} catch (FilesystemException $ex) {
throw new PhutilProxyException(
pht(
'Configuration file "%s" exists, but could not be read.',
$path),
$ex);
}
try {
$result = phutil_json_decode($data);
} catch (PhutilJSONParserException $ex) {
throw new PhutilProxyException(
pht(
'Configuration file "%s" exists and is readable, but the content '.
'is not valid JSON. You may have edited this file manually and '.
'introduced a syntax error by mistake. Correct the file syntax '.
'to continue.',
$path),
$ex);
}View on GitHub (pinned to 5720a38cfe)
Solutions
- Fix read permission and ownership for the web/daemon user: chmod 644 conf/local/local.json (or 640 with matching group) and chown it to the account running PHP.
- Confirm the path is a regular file: ls -la conf/local/local.json; if it was replaced by a directory or symlink loop, restore a real file.
- Verify by running `./bin/config get` as the web user; it should now parse the JSON (a follow-up PhabricatorConfigLocalSource error will appear if syntax is broken).
Example fix
# before: unreadable by the web user $ ls -l conf/local/local.json -rw------- 1 root root 532 local.json # after $ sudo chown www-data:www-data conf/local/local.json $ sudo chmod 640 conf/local/local.json
Defensive patterns
Strategy: validation
Validate before calling
$path = 'conf/local/local.json';
if (file_exists($path) && !is_readable($path)) {
throw new Exception("Fix permissions before continuing: $path");
} Prevention
- Provision conf/local/local.json with explicit mode 640 and the web user's ownership in your config management.
- Never run ./bin/config as root without fixing ownership afterwards.
- Smoke-test after permission playbooks: sudo -u www-data ./bin/config get must succeed.
When it happens
Trigger: chmod/chown that removes read permission from conf/local/local.json (root-owned after running daemons as root, then serving as www-data); the file being replaced by a directory; a container image that copied the file with mode 600 for another UID; disk/FS errors surfaced as FilesystemException.
Common situations: After automation or restoring backups as root, file ownership becomes root:root and the PHP-FPM user cannot read it; hardening playbooks that recursively tighten permissions under conf/; Docker/Kubernetes volume mounts overriding file modes.
Related errors
- Configuration file "%s" exists and is readable, but the cont
- Failed to create directory "%s" for specified log file (with
- Failed to create directory "%s" for specified PID file. You
- Failed to open output file "%s" for writing.
- Config option "phd.user" is not set. You must set this optio
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/c01556cf10d15e85.
Report an issue: GitHub.