DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
VGSources
Blog

Fix “Permission Denied” When Uploading to /var/www on Linux

Find the real cause of permission denied under /var/www, test access as the web-service account, and apply a narrow deploy-group or ACL fix without resorting to chmod 777.
Length8 min Posted Quest giverVGSources Team

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A Linux upload fails with Permission denied when the account performing the upload cannot traverse the path or cannot write to the destination directory. The account you use over SSH may not be the account running the web application. Inspect both identities and every directory in the path, then grant write access only to the required upload directory. Do not solve the problem with chmod 777.

Why Linux refuses the upload

Linux evaluates an operation using the effective user and group IDs of the process. For a path such as /var/www/example/uploads, that process must be able to cross /var, /var/www, /var/www/example, and finally uploads. A directory’s permissions have distinct meanings: read permits listing entries, write permits creating or deleting entries, and execute permits crossing or searching the directory. The Debian Handbook explains directory rights in these terms.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

That means a writable-looking file does not prove that an upload can succeed. Creating a new file requires write and execute permission on the destination directory. Deleting or replacing an existing file also depends on the containing directory. A parent directory without execute permission causes denial before Linux reaches the target.

The identity is often the surprise. Your interactive shell might be logged in as deploy, while a web server or application worker runs as www-data on Debian and Ubuntu. Other distributions commonly use a different account, such as apache. Documentation for web applications such as Nextcloud’s source installation also stresses verifying the actual service user instead of assuming one universal name.

Diagnose before changing permissions

Run the inspection as the user who sees the failure, and substitute your real site and upload path. These commands reveal the acting identity, permissions on every path component, ownership, and any access-control lists:

id
namei -l /var/www/example/uploads
ls -ld /var/www /var/www/example /var/www/example/uploads
stat -c '%A %U:%G %n' /var/www /var/www/example /var/www/example/uploads
getfacl -p /var/www/example/uploads

id shows the account and supplementary groups for the current shell. namei -l is particularly valuable because it displays each component rather than only the final directory. In the ls or stat output, check the owner, group, and whether the relevant class has x on every directory and wx on the upload directory. getfacl exposes ACL entries that ordinary mode bits do not show.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do not test only as your SSH user. Test with the service identity that actually handles the HTTP request. On a Debian or Ubuntu system where the configured account is www-data:

sudo -u www-data touch /var/www/example/uploads/.perm-test
sudo -u www-data rm /var/www/example/uploads/.perm-test

A successful create-and-remove test confirms that the service account can traverse the path and modify the directory. A failure tells you the web process still lacks an effective permission, regardless of what your own account can do. Replace www-data with the account configured for your server; using the wrong name can produce a misleading diagnosis.

Choose the narrowest access model

There are three common approaches. The first two can be made narrow and auditable; the third is intentionally included only to explain why it is unsafe.

Approach Identity receiving access Write scope New-file inheritance Auditability and risk
Deploy owner plus web-server group The deploy account owns the tree; the configured web account uses the shared group. Only directories such as uploads or cache are group-writable. Setgid directories can make new entries inherit the directory group, but filesystem and mount behavior must be verified. Simple to inspect and reverse. A compromised web process can write only where the group is granted write permission.
ACL exception A named service account receives an ACL entry without changing the principal owner or group. Can be limited to one directory or even a particular operation. Default ACLs can be applied so descendants inherit the intended entry. Fine-grained, but administrators must inspect ACLs with getfacl; mode bits alone are incomplete.
World-writable mode (chmod 777) Every local user and process. Any process that can reach the directory may create, replace, or delete files. Broad access persists unless manually removed. Hard to audit and exposes the site to unrelated users and a compromised web process. Do not use it as a fix.

The deploy-user-plus-group layout is usually the easiest to maintain. Use an ACL when changing the main group would affect other workflows or when only one service needs an exception.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Apply a deploy-user and web-group layout

The following sequence is a concrete baseline. Replace deploy, www-data, and /var/www/example with the accounts and path on your host. Review the path before running recursive commands; ownership changes affect the entire tree.

  1. Assign the site to the deployment owner and web group.
    sudo chown -R deploy:www-data /var/www/example

    This makes the deploy account the owner while allowing the web service to use group permissions. If your service runs as apache, use that group instead.

  2. Set directory and regular-file modes separately.
    sudo find /var/www/example -type d -exec chmod 2755 {} +
    sudo find /var/www/example -type f -exec chmod 644 {} +

    The leading 2 sets the setgid bit on directories, while 755 gives the owner full access and read/execute access to group and other. Regular files receive 644, so they are not accidentally executable. Applying chmod -R 755 would mark ordinary files executable; applying chmod -R 644 would remove directory traversal and break access.

  3. Open only the upload directory for group writing.
    sudo chmod 2775 /var/www/example/uploads

    Here 775 gives the owner and group read, write, and execute rights, and the leading 2 preserves setgid so newly created entries normally use the directory’s group. If the application also writes a cache, temporary directory, or generated media directory, grant the same treatment only to those named directories, not to the whole document root.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  4. Test as the service account, then remove the test file.
    sudo -u www-data touch /var/www/example/uploads/.perm-test
    sudo -u www-data rm /var/www/example/uploads/.perm-test

    If both commands succeed, retry the application upload. If they fail, return to namei -l and getfacl; the effective path or ACL still needs attention.

Setgid inheritance is not a promise that every filesystem and mount configuration will behave identically. Confirm the result after a real test by checking the new file’s group with stat or ls -l, rather than assuming it inherited the expected group.

Use an ACL when ownership should not change

If another account must remain the owner, grant the service account a narrowly scoped ACL on the upload directory:

sudo setfacl -m u:www-data:rwx /var/www/example/uploads
sudo setfacl -d -m u:www-data:rwx /var/www/example/uploads
getfacl -p /var/www/example/uploads

The first command grants the current service account read, write, and execute access to that directory. The second adds a default ACL so newly created children can inherit an entry for the service account. A default ACL also has a mask and base entries; inspect the complete result with getfacl and adjust the mask or default group/other entries if they are broader than your policy. Apply the same ACL to each additional directory the application must write, not to /var/www indiscriminately.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

ACLs are easy to overlook during later troubleshooting because ls -l shows only a summary (often a + after the mode). Always include getfacl when an apparent owner/group fix has no effect. The Debian Handbook’s rights-management guidance covers the relationship between traditional modes and ACLs.

If you cannot change the owner

When policy prevents a recursive chown, add the service account to the existing owning group through your system’s account-management procedure, then make only the required upload directory group-writable. Re-run id for the service account (or restart the service so it receives updated supplementary groups) and verify the directory’s group and mode. Do not make the entire site world-writable merely to avoid an ownership decision.

An ACL is the alternative when adding group membership is undesirable. It leaves the principal owner and group intact while recording exactly which service account receives access. Keep the ACL limited to the upload, cache, or other generated-content directories and document it so a later administrator does not remove it accidentally.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Fix the common failure modes

The target directory looks writable, but the upload still fails

Inspect every parent with namei -l. A missing execute/search bit on /var/www or the site directory blocks traversal even if uploads itself shows rwx. Correct the parent permission for the required owner or group, then repeat the service-account test.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The SSH test works but the application test fails

Your SSH account and the web worker are different identities. Confirm the configured service account in the web-server or application configuration, then use sudo -u with that exact account. On Debian and Ubuntu it is commonly www-data; other distributions may use apache or another dedicated user.

A recursive mode change broke the site

Directory and file modes are not interchangeable. Restore directories with traversal permission and regular files with non-executable modes, using separate find -type d and find -type f operations. Reapply group write only to directories that genuinely need it.

chown itself returns an error

chown can fail with EACCES, EPERM, or EROFS. The Linux chown(2) documentation notes causes including insufficient privilege, a read-only filesystem, immutable or append-only attributes, and NFS UID mapping. Resolve the underlying filesystem or identity issue before attempting more permission changes. If the filesystem maps numeric IDs differently over NFS, an apparently matching username may not represent the same owner on the server.

New files receive an unexpected group

Setgid usually causes group inheritance on directories, but filesystem and mount behavior can affect the result. Create a harmless test file as the service account and inspect its owner and group with stat. If the group is wrong, verify the setgid bit, the effective service identity, ACL defaults, and the filesystem’s documented behavior instead of widening permissions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

An ACL appears to be ignored

Run getfacl -p on the directory and its parents. Check the ACL mask as well as the named-user entry: a restrictive mask can limit the effective rights displayed for www-data. Also confirm that the request is handled by the account to which the ACL was granted.

Keep uploads safe after the fix

  • Grant write access only to directories that must receive generated or uploaded content; keep application code and configuration owned by the deploy account and non-writable by the web process where practical.
  • Use setgid or default ACLs deliberately, then verify the owner and group of newly created files.
  • Record any ACL exception and periodically inspect it with getfacl.
  • Retain the service-account create-and-remove test as a diagnostic, but remove the test file immediately.
  • Never treat chmod 777 as a routine repair. It gives every local user and compromised process write access and hides whether the real problem was ownership, traversal, an ACL, or the wrong service identity. The troubleshooting guidance at CubePath likewise recommends diagnosing the path before changing modes.

For mode syntax and special bits such as setgid, see the GNU Coreutils mode-structure documentation.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.