A **Symfony cache clear permission denied** error usually means the process running Symfony cannot create, remove, or write files in `var/cache`. It may appear during a deployment, after switching PHP-FPM settings, while running `bin/console cache:clear`, or only when real web traffic reaches the application.
The tempting response is to make the directory globally writable. That can restore service briefly, but `chmod -R 777 var` is rarely a sound fix. It hides the actual mismatch between the deployment user, the web server user, background workers, and file ownership—and it can create a security and maintenance problem later.
This guide explains how to identify which process needs access, correct permissions safely, clear and warm the cache in the right order, and avoid causing a second outage while fixing the first.
If the failure is blocking a release or producing customer-facing errors, targeted [Symfony Bug Fixing](https://phprescue.dev/services/symfony-bug-fixing/) can help trace the exact runtime and deployment mismatch.
## Recognize the error before changing permissions
The wording varies by operating system, PHP version, Symfony version, and deployment tool. Common messages include:
– `Permission denied` while removing or creating a directory below `var/cache`
– `Unable to write in the cache directory`
– `Failed to open stream: Permission denied`
– failure to write container, route, Twig, or annotation/attribute metadata cache files
– a successful CLI command followed by a production web request that fails
Start with the full error, including the path. A failure in `var/cache/prod` is different from a problem in `var/log`, a session directory, a release symlink, or a mounted volume. Do not assume that a message from `cache:clear` means Symfony itself is at fault; Symfony is often correctly reporting an operating-system permission restriction.
## Why Symfony cache permissions break
Symfony needs writable runtime directories. In a typical project, `var/cache` contains generated files that allow the application to run efficiently. The exact content changes by environment and framework version, but Symfony must be able to create and update the relevant cache files.
The failure commonly begins when different processes operate as different system users:
– a developer or deployment account runs `bin/console`
– PHP-FPM runs requests as `www-data`, `nginx`, `apache`, or a hosting-specific user
– a queue worker, scheduler, or Supervisor-managed process runs under another account
– a release script creates directories with restrictive ownership or umask settings
For example, a deploy account may run `php bin/console cache:warmup` and create files owned by that account. PHP-FPM may then be unable to modify the resulting cache directory. The opposite can also happen: the web process creates cache files that the next deployment cannot remove.
Container deployments add another version of the same problem. A build stage might create cache files as `root`, while the final container intentionally runs as an unprivileged user. A mounted persistent volume can also retain ownership from an older container image or host user.
## First, identify the user for each relevant process
Before changing ownership, establish who actually needs write access. On a Linux server, the commands and service names depend on the environment, but the goal is consistent.
Check the ownership and permissions of the affected path:
“`bash
ls -ld var var/cache var/cache/prod
ls -la var/cache | head
“`
Then identify the PHP-FPM pool user and group in its configuration. Depending on the server, pool files may be under locations such as `/etc/php/*/fpm/pool.d/`. Look for entries similar to:
“`ini
user = www-data
group = www-data
“`
For Apache with mod_php, the web server process user matters. For a managed platform, consult its process configuration rather than guessing. For workers, review the Supervisor, systemd, container, or platform definition that starts them.
Also confirm the account that runs the deployment commands. SSH deployments, CI runners, release tools, and scheduled tasks may all use different users. Record the answer to this practical question: **which users need to write to `var/cache`, and when?**
This is more reliable than applying permission commands copied from an unrelated hosting setup.
## Check every parent directory, not just `var/cache`
A process needs more than write permission on the final folder. It generally needs execute (traverse) permission on parent directories in the path. A restrictive project root, release directory, or home directory can therefore produce a permission denied error even when `var/cache` itself looks writable.
Use this command where available:
“`bash
namei -l /full/path/to/project/var/cache
“`
It displays permissions along the entire path. Look for a parent folder that prevents the PHP runtime user from traversing into the project. This is particularly common where releases live beneath a private deployment account’s home directory.
Do not loosen parent-directory permissions indiscriminately. Instead, grant only the intended runtime user or group the access required to reach the application directory.
## Apply a safe ownership and group strategy
There is no universal command that fits every server. The correct strategy depends on who deploys and who serves traffic. A common approach is to use a shared group for the deployment account and the web runtime account, then make runtime directories group-writable.
For a site where the web group is `www-data`, the shape of the solution may look like this:
“`bash
chown -R deploy-user:www-data var
find var -type d -exec chmod 2775 {} ;
find var -type f -exec chmod 664 {} ;
“`
Treat the names and modes as an example, not a command to run blindly. The `2` in `2775` sets the setgid bit on directories, so new files commonly inherit the directory group. That helps prevent the next cache warmup from recreating the ownership mismatch.
The appropriate file modes vary by hosting and security policy. More importantly, avoid making application files owned by the web server user merely because it seems convenient. Keep write access limited to directories that genuinely need it, typically runtime locations such as `var/cache` and `var/log`.
If group membership has just changed, the affected user may need to start a new shell session, and PHP-FPM or workers may need a controlled reload to recognize the updated group context.
## Use ACLs when several users need reliable access
Traditional Unix owner/group permissions are sometimes not enough. This is common when a deploy user, PHP-FPM user, and worker user must all write to the same directories, or when hosting conventions prevent a clean shared group arrangement.
Filesystem ACLs can grant explicit access to the necessary user while preserving narrower default permissions. For example, an administrator may set an ACL for the web user and a default ACL so newly created cache files inherit access. Exact commands and support vary by filesystem and host, so verify that ACLs are enabled before relying on them.
ACLs are useful when deliberately designed. They are not a substitute for understanding the runtime model. After applying them, test both the CLI deployment command and an actual HTTP request, because those may run under different users.
## Clear and warm the cache in a controlled order
Once permissions are correct, run Symfony commands using the same account intended by the deployment process. In production, use the environment explicitly when appropriate:
“`bash
APP_ENV=prod APP_DEBUG=0 php bin/console cache:clear
APP_ENV=prod APP_DEBUG=0 php bin/console cache:warmup
“`
Avoid deleting `var/cache` during live traffic without considering the deployment method. Removing a cache directory while requests are in progress can cause temporary failures, repeated rebuilding, or an application state that differs across servers.
A safer approach is usually to:
1. Put the permission correction into the deployment procedure rather than treating it as a one-off server repair.
2. Build or warm the cache using the intended release and runtime users.
3. Switch traffic or the release symlink only after the application is ready, where the deployment design supports it.
4. Verify a normal page, an authenticated path if relevant, and a critical application action.
5. Review logs for fresh permission messages after the change.
On multi-server environments, perform the equivalent checks on every node. Fixing one server may only turn an intermittent production failure into a harder-to-diagnose problem.
## Do not use chmod 777 as the permanent answer
`chmod -R 777 var` makes directories writable by every local user. It can conceal the root cause and may be unacceptable on shared systems. It also does not address an incorrect deploy process that repeatedly creates files with the wrong owner.
A broad permission change can be useful only as a tightly controlled, short diagnostic test in a non-production environment, followed immediately by a properly scoped correction. It should not become the deployment standard.
Similarly, avoid running all console commands as `root` just to make the error disappear. Root-created cache files often cause the next permission failure when the web user or deployment user tries to replace them.
## Verify the fix from both CLI and web contexts
A green `cache:clear` result is necessary but not sufficient. Test the routes and commands that matter to the application:
– a standard public request handled by PHP-FPM or the web server
– a route that uses Twig, the service container, and configuration
– a worker or scheduled command, if it shares the runtime directory
– the next deployment or release preparation step
Check the Symfony logs and PHP-FPM or web-server logs after testing. A partial fix may allow cache removal but still prevent cache warmup, log creation, or later writes under a different user.
If the application is currently unavailable, checkout is failing, or a release has left production unstable, use an incident-first approach and consider [Emergency Website Bug Fixing](https://phprescue.dev/services/emergency-website-bug-fixing/) rather than repeatedly changing live filesystem permissions.
## Prevent the same Symfony cache error on the next deployment
The long-term fix belongs in deployment configuration. Define the intended user and group, ensure required directories exist with the expected permissions, and run cache warmup consistently. If a container image is involved, ensure the final runtime user can write to the runtime path—or arrange the cache build and runtime filesystem so no write is required where it should not be.
Document the relevant facts: deployment account, web runtime account, worker account, writable directories, and the commands used to warm the production cache. This makes a future server migration, PHP-FPM change, or CI update much less likely to recreate the outage.
## Frequently asked questions
### Why does cache:clear work over SSH but fail on the website?
The SSH command and website usually run as different system users. The SSH user may own `var/cache`, while PHP-FPM lacks permission to write there. Test ownership and permissions from both contexts.
### Can API Platform or Sylius on Symfony have the same cache permission issue?
Yes. API Platform and Sylius run on Symfony and can surface the same underlying filesystem problem. The affected cache files or routes may differ, but the solution still starts with identifying the actual runtime users and required write paths.
### Laravel instead?
Laravel has its own cache and storage paths, so use a Laravel-specific workflow rather than applying Symfony commands. The general principle—matching deployment and runtime permissions—still applies.
### Need a Symfony bug fixed?
If you have the complete error, the affected URL or command, recent deployment details, and non-sensitive server context, those details can make a Symfony cache permission issue much faster to trace and fix.
