Infrastructure

Magento File Permission and Ownership Failures

Ownership problems cause intermittent Magento failures that fool teams for hours. Here is the two-user model, the writable directories, and how to diagnose it.

Jason Schuman · February 5, 2026

Permission problems fail intermittently, which is why they fool people

File ownership and permission problems rarely take a Magento store down cleanly. They cause intermittent failures: a cache that sometimes will not write, a static deploy that fails on one server, an admin action that works for one user and not another.

Because the symptom moves around, teams chase the wrong cause for hours. The real problem is often a file owned by the wrong user or a directory the web server cannot write to.

This article covers the two-user ownership model Magento expects, the directories that must stay writable, and how to diagnose the failures that ownership problems create.

The two-user model Magento expects

A correctly configured Magento server has two identities in play. One is the deploy or file-system owner that owns the code, and the other is the web server user that serves requests.

The pattern that works is files owned by the deploy user, with the web server user in the owning group, and the directories that need runtime writes made group-writable. This lets deploys own the code while the web server can still write where it must.

When one user owns everything, or when files land owned by root, the web server loses the access it needs and the intermittent failures begin.

The directories that must stay writable

Magento writes to a specific set of directories at runtime and during deploys. These have to be writable by the web server user, or by whichever process is running:

  • var/, for cache, logs, and session data.
  • generated/, for compiled code and interceptors.
  • pub/static, for deployed static assets.
  • pub/media, for product images and uploads.
  • app/etc, which must be writable during setup but locked down afterward.

A permission problem in any of these produces a distinct failure, from static deploys that error to a cache that silently fails to write.

How files end up owned by the wrong user

The usual cause is a command run as the wrong user. A deploy step or a cron job run as root creates files owned by root, and the web server user can no longer read or overwrite them.

A cron job or CLI command run as root leaves files the web server cannot touch. The store then fails intermittently on exactly the requests that need those files, with no obvious pattern.

The umask of the process that creates files matters too. A restrictive umask can strip the group-write bit that the two-user model depends on, so files are created without the access the web server needs.

Setting permissions correctly

Magento's own guidance is to set ownership and group-writable permissions across the runtime directories after deployment. The pattern uses find to apply directory and file permissions separately.

find var generated vendor pub/static pub/media app/etc -type f -exec chmod g+w {} +
find var generated vendor pub/static pub/media app/etc -type d -exec chmod g+ws {} +
chown -R deployuser:webservergroup .

The setgid bit on directories, applied by g+ws, matters because it makes new files inherit the group. That keeps the two-user model intact as the store writes new cache and static files over time.

Diagnosing an ownership problem

When failures are intermittent and tied to writing files, start with ownership. List the owner and group of var/, generated/, and pub/static, and confirm they match the two-user model.

Check which user cron runs as, because a cron running as root is a common source of unreadable files. The permission-denied and "cannot create directory" errors in exception.log and the web server log usually name the exact path that is failing.

Once you see a file owned by root in a directory the web server must write, the intermittent failure usually has its explanation.

Lock down what should not be writable

The flip side of writable runtime directories is that some paths should not be writable at all in production. The app/etc directory needs write access during setup, and should be read-only once the store is configured.

Leaving configuration and code writable by the web server is a security exposure, because a compromised process can then modify the files it runs. The healthy pattern is writable where Magento needs runtime output, and read-only everywhere else.

Production mode assumes this split. It does not generate code or static content on the fly, so the web server does not need write access to code paths, only to var, pub/static, pub/media, and generated.

Small cause, outsized confusion

Permission and ownership problems are among the cheapest issues to fix and the most expensive to misdiagnose. The fix is often a single chown, but only after the wrong theory has cost an afternoon.

Knowing that your ownership follows the two-user model, and that cron and deploys run as the right user, removes a whole category of intermittent failure. That confirmation is a quick, high-value check in any infrastructure review.