An NFS permission denied error means the client reached the export but the server rejected the requested file operation. The failure often appears when a user can mount a share but cannot list, create, or change files under the mounted path. Troubleshooting it in order avoids changing client mount files when the real access decision is happening on the server.

For sec=sys mounts, the server checks numeric UID, GID, supplementary groups, export options, and normal filesystem permissions. root_squash maps client root to the anonymous user, so testing only with sudo on the client can hide or create a different failure from the one affecting the application user. NFSv4 identity mapping can also show files as nobody when the name mapping domain does not match.

Use the exact mounted path and the exact user that saw the denial. If the export uses Kerberos, match the security flavor and credentials before changing Unix modes; if the export is read-only or restricted to another client network, fix the export definition and reload it before changing ownership.

Steps to troubleshoot NFS permission denied errors:

  1. Reproduce the denial from the client as the affected user.
    $ touch /mnt/projects/report.txt
    touch: cannot touch '/mnt/projects/report.txt': Permission denied

    Use the same account, command, application path, and mount point that first reported the failure. If only client-root access fails, root_squash may be working as intended.

  2. Identify the mounted NFS source and security flavor.
    $ findmnt -t nfs,nfs4 /mnt/projects
    TARGET        SOURCE                              FSTYPE OPTIONS
    /mnt/projects files.example.net:/srv/nfs/projects nfs4   rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,hard,proto=tcp,timeo=600,retrans=2,sec=sys

    If the path is not listed, troubleshoot the mount itself before changing export permissions.

  3. Check the active export rule on the NFS server.
    $ sudo exportfs -v
    /srv/nfs/projects
            192.0.2.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,root_squash,no_all_squash)

    If the output shows ro, a missing client selector, or a different sec= value from the client mount, correct the saved export definition and reload it before changing filesystem ownership.

  4. Check the server-side directory ownership and mode with numeric IDs.
    $ ls -ldn /srv/nfs/projects
    drwxrws--- 2 0 2000 4096 Jun  6 09:20 /srv/nfs/projects

    Numeric IDs avoid name-service confusion. In this example, UID 0 owns the directory, GID 2000 has group access, and the setgid bit keeps new files in the shared group.

  5. Check the affected user's numeric identity on the client.
    $ id appuser
    uid=1001(appuser) gid=1001(appuser) groups=1001(appuser)

    The user must map to an owner, group, ACL, or anonymous identity that the server path permits. For centrally managed accounts, make the change in the identity service instead of only on one host.

  6. Fix the user's shared group membership when the directory group should grant access.
    $ sudo usermod --append --groups projectusers appuser

    This local-account example adds appuser to the group that maps to GID 2000. Start a new login session for the user or restart the affected service so the new supplementary group list is used.

  7. Set the intended shared group on the exported directory when the server path is owned by the wrong group.
    $ sudo chgrp projectusers /srv/nfs/projects

    Do this only after confirming which group should own the shared data. Changing ownership on an active export can affect every client using that path.

  8. Set group-write and setgid mode on the exported directory.
    $ sudo chmod 2770 /srv/nfs/projects

    Use a narrower mode or POSIX ACL when only selected users should write. The setgid bit keeps newly created files under the directory's group, but it does not replace account and group mapping.

  9. Reload exports only when you changed /etc/exports or a file under /etc/exports.d.
    $ sudo exportfs -rv
    exporting 192.0.2.0/24:/srv/nfs/projects

    Permission-only changes from chown, chgrp, chmod, or ACL tools take effect through the filesystem and normally do not require an export reload.

  10. Confirm that the client session now includes the shared group.
    $ id appuser
    uid=1001(appuser) gid=1001(appuser) groups=1001(appuser),2000(projectusers)

    If the group is still missing, log out and back in, refresh the service process, or fix the directory-service membership before retesting the NFS path.

  11. Retest the original client write.
    $ touch /mnt/projects/report.txt

    No output from touch means the file was created or its timestamp was updated successfully.

  12. Verify the created file has the expected owner and group.
    $ stat -c '%U %G %A %n' /mnt/projects/report.txt
    appuser projectusers -rw-r--r-- /mnt/projects/report.txt

    If the file still shows nobody or an unexpected group, compare the NFSv4 domain and mapping settings in /etc/idmapd.conf on the participating systems, then clear stale idmap cache entries or restart the affected NFS client service according to the distribution's service layout.