A refusal of access under Linux does not always come from a forgotten chmod. The failing command may be running with a different UID, or its account may not belong to the expected group. Before changing an owner, start by identifying the account actually being used.
The id command displays the UID, primary group, and secondary groups of the current process. This is the starting point when a script, service, or SSH session does not see the same file as you do.

Read UID, GID, and groups with id
Run id without arguments in the session that poses the problem:
id
An output like uid=1000(alex) gid=1000(alex) groups=1000(alex),27(sudo),999(docker) describes the identity of the process. uid is the user identifier. gid is the primary group. groups adds the secondary groups, often those that grant access to Docker, logs, or a share.
To retrieve just one value, use the following options:
id -udisplays the effective UID.id -gdisplays the effective GID.id -Gnlists the names of the groups.id -undisplays the name of the effective account.
The difference between real and effective identifier mainly appears after sudo, in a SUID binary or with some tools that switch users. For a quick check of the name alone, also refer to our article on whoami and the effective user.
Inspect a user account without opening its session
Add the account name to query its local record. This command reads the user database and does not log you into that account:
id www-data
id -Gn www-data
On Debian and Ubuntu, www-data is often the account for web services. On another distribution, the service may use apache, nginx, or an application account. Check the unit file or service configuration instead of taking this example as it is.
After adding a user to a group, an already open session may retain its old list of groups. Log out and then log back in before concluding that the change has failed. The id user command re-reads the database, but id alone always describes your current process.
Compare the account identity and file rights
Knowing the groups is not enough. You must then read the owner, group, and permissions of the relevant path:
id
stat -c '%U %G %A %n' /path/to/file
namei -l /path/to/file
stat indicates who owns the file. namei -l also displays the rights of each directory in the path. A readable file is useless if the account cannot traverse the parent directory, which requires x permission on that directory.
Do not fix a denial with chmod 777. First compare the file’s group with id -Gn, then adjust the owner, group, or needed permissions. To review groups and their usages, read group management under Linux. If you need to change permissions, our guide on recursive chmod explains why a command that is too broad may affect far more files than expected.
Test under the relevant account before modifying sudo
When you have administrative rights, execute only the check under the account that encounters the problem:
sudo -u www-data id
sudo -u www-data test -r /path/to/file && echo readable
sudo -u www-data test -x /path/to/directory && echo traversable
The first call confirms the effective identity. The next two respond to a specific question, reading the file or traversing the directory. Replace www-data and the paths before execution. Do not use sudo -u to launch a production application just to test its rights.
If access remains denied even though UID, group, and Unix permissions seem correct, also check the ACLs with getfacl, network mounts, and SELinux or AppArmor depending on your distribution. These mechanisms can impose a rule above the standard rights.
With id, stat, and a test under the correct account, you know where to look before modifying rights blindly.