wp-config.php to permission mode 400 or 440. The logic sounds solid at first glance: the file contains your database credentials, authentication salts, and security keys, so making it strictly read-only for its owner should prevent untrusted code from modifying it. Shortly after making this change, however, website owners often run into automated background update failures, stalled core upgrades, or persistent error messages in the WordPress dashboard warning that files cannot be updated.
Understanding why this happens requires looking at how web servers execute PHP, how WordPress checks its environment before performing upgrades, and what read-only flags mean to an automated maintenance process. Here are the common questions that come up when permission hardening breaks update automation.
Why do security guides recommend chmod 400 in the first place?
chmod 400 grants read-only rights to the user who owns the file, while stripping all permissions—read, write, and execute—from the file group and everyone else. The goal of this configuration is privilege minimization. If an unauthorized process or another user on a multi-tenant server attempts to read your database credentials, the operating system blocks the request immediately.
This hardening practice originally gained traction in environments where web servers ran under shared accounts or older configurations such as Apache with mod_php. In those setups, the web server ran as a generic user like www-data or nobody. Setting strict group and world permissions was a blunt way to stop neighboring users from viewing credentials. On modern systems, though, isolating configuration files usually happens through user mapping rather than eliminating write flags for the owner.
While reading credentials during runtime only requires read access, administrative tasks require more. When administrators apply chmod 400 indiscriminately, they often forget that administrative maintenance routines executed through the web interface run under the exact same user identity as normal visitor traffic.
How does the PHP execution model change who touches wp-config.php?
appuser, every PHP script triggered by an HTTP request runs with the system privileges of appuser.
Because PHP runs directly as the owner, setting a file to 400 means you are explicitly telling Linux that appuser is forbidden from writing to that file. When traffic spikes or administrative jobs trigger worker pools—a dynamic explained in our review of diagnosing PHP-FPM pool bottlenecks—the spawned workers inherit those exact constraints.
If your PHP process ran as www-data and your files were owned by appuser, a mode of 400 would stop PHP from even reading the file unless group permissions or Access Control Lists (ACLs) were added. But in typical shared, VPS, and managed environments where pool users match file owners, 400 turns the file into an owner read-only resource, preventing the very user responsible for maintaining the application from making modifications.
Why does WordPress need to write to wp-config.php during updates?
WP_Filesystem. Before applying core, plugin, or theme updates, this system performs safety checks to verify that the environment allows in-place file replacement. If the filesystem abstraction layer detects that critical core files or the root directory lack write permissions, it can halt the entire process to prevent leaving the site in a broken, partially updated state.
While most WordPress minor updates replace files inside wp-admin and wp-includes, major core updates sometimes need to update configuration directives, add new security salts, or adjust database options defined in wp-config.php. Many popular managed hosting toolkits, command-line updaters, and caching plugins also inject or adjust flags in wp-config.php during maintenance windows.
When WordPress or its update runner executes an update, it typically writes data to a temporary file in the same directory, verifies its integrity, and renames it over the target file. If wp-config.php itself has mode 400, or if the parent directory has restrictive permissions, any script trying to overwrite or modify the configuration fails with a filesystem error. The update halts, leaving the installation on an outdated release.
How can you test the current permissions and repair them?
BASH
# Check the current ownership and permissions
ls -l wp-config.php
# Restore owner write access while protecting group and world
chmod 600 wp-config.php600 is the standard compromise. It allows the owner—and therefore the PHP worker executing your updates—to read and write to the file, while completely blocking group members and the public from reading or writing to it.
If your setup requires the web server to access files through a shared group (for example, if the file is owned by your deployment user but read by a web server pool in the same group), mode 640 or 644 might be necessary depending on your server's security model.
What is the best way to protect credentials without breaking updates?
wp-config.php one directory above your web document root. WordPress natively looks one level up from the root directory if it cannot find wp-config.php inside the public folder, provided another wp-config.php does not already exist there.
Moving the configuration file above the document root prevents web servers from ever serving it directly, even if a server misconfiguration causes PHP parsing to fail. Keep the permissions set to 600 so the PHP process owner can still manage the file during automated operations, while web crawlers and unauthorized local users remain locked out.
Balancing file security with automated maintenance comes down to understanding process identity. Locking files down to read-only modes like 400 offers a false sense of security when the process you are trying to restrict is the exact same process you rely on to keep the core software patched and secure.