Permissions broke my service: a fix order that works
Updated

Permission-denied service failures, diagnosed in a fixed order: reproduce, name the users, then apply the narrowest repair.
Permission denied is the most honest error on a Linux machine. It tells you exactly what happened: this user asked for that file, and the mode bits said no. Most engineers still fix it by widening permissions until the error disappears, which works once and weakens the machine forever.
The fix order
Reproduce from the service user's side. Run the failing read as the service account, or reason from id and ls -l output where privilege switching is unavailable. Copy the exact denial line into your notes before touching anything.
Name the two users. The reader (the process user) and the owner (the file owner). Then name the applicable permission column: user, group or other. Guessing the repair before this step is how machines end up world readable.
Apply the narrowest repair. Two candidates cover most cases: put the reader in the file's group with mode 640, or transfer ownership to the reader with mode 600. Pick one, write down why the other is worse here, then verify as the service user.
Worked example: a fictional config nobody could read
The context below is fictional. A fictional deploy user, deploysvc, serves config from /srv/app/config.env, owned by a human account at mode 600. After a laptop reinstall the file was re-copied, the owner changed, and the service started failing with permission denied.
Reproduction as the service user shows the denial on the exact file. The two users are deploysvc (reader) and the human account (owner); the applicable column is user-only, so group and other are closed. The repair: create an appconfig group, add deploysvc, set the file to group appconfig at 640. Verification as deploysvc reads the file; verification as an unrelated user still fails. Narrow, proven, done.
Decision table: the two common repairs
| Situation | Repair | Why |
|---|---|---|
| Several service users share the file | Group read (chgrp + 640) | One group change covers all readers, owner keeps control |
| Exactly one reader, sensitive content | Owner change (chown + 600) | No group to manage, nobody else gains anything |
| Unknown reader set | Stop and find out first | Widening blind is how secrets leak |
Checklist: a permission fix you can defend
- The exact denial line is in your notes.
- Reader, owner and permission column are named.
- The rejected alternative has one written reason.
- Verified as the service user, and as an unrelated user (still denied).
Related reading
- Practice it free in the browser: Fix the Service That Permissions Broke.
- DevOps Foundations puts permissions in Module 1, where they belong.
Straight answers
Frequently asked questions
Why not just chmod 777 and move on?
It trades a five minute diagnosis for a permanent open door. The next audit, the next incident, or the next teammate pays for it.
chown or chgrp, which first?
Neither first. Reproduce and name the two users first; the choice between group read and owner change follows from that.
How do I prove the fix?
Verify as the service user, not as root. If the service account can read it and nobody else gained access, the fix is done.