chmod: invalid mode

Fixing 'chmod: invalid mode' when setting permissions on symlinks

Linux & Unix Intermediate 👁 2 views 📅 May 29, 2026

Getting 'invalid mode' when trying to chmod a symlink? It's not a typo—chmod has specific rules for symlinks. Here's why and how to fix it.

When this error pops up

You're setting up a project directory, and you've got a symbolic link pointing to a config file. You run something like chmod 644 /path/to/link and get slapped with chmod: invalid mode: ‘/path/to/link’. Or maybe it says chmod: cannot access '/path/to/link': No such file or directory. It's not a typo — you typed the mode correctly. The problem is symlink.

I've seen this most often in CI/CD scripts or when someone's moving files around by hand and forgets that chmod has a mind of its own with symlinks. On Linux, if the symlink points to a file that doesn't exist yet (a dangling symlink), you'll get that error. Even if it does exist, you can't change symlink permissions directly using the normal syntax.

Root cause — chmod doesn't touch symlinks by default

Here's the deal: Linux permissions on symlinks don't actually matter. The kernel ignores them. When you run chmod on a symlink without special flags, it follows the link and changes the target file's permissions. If the target doesn't exist, you get the 'invalid mode' or 'cannot access' error because chmod is trying to resolve a path that isn't there.

But wait — even if you want to change the symlink's own permissions (for fun, or because some weird filesystem requires it), you can't do it with the default chmod command. You have to tell it explicitly.

The fix — use -h or --no-dereference

  1. Identify if it's a dangling symlink:
    Run ls -l /path/to/link. If the target path is highlighted in red or shows an arrow pointing to a nonexistent file, it's dangling. That's your problem.
  2. Fix the target first (recommended):
    If you want to change permissions on the target file, make sure the symlink points to a real file. Then run:
    chmod 644 /path/to/link

    This follows the link and changes the target. No error.
  3. Change symlink permissions directly:
    If you genuinely need to change the symlink's own permissions (rare, but some backup tools check them), use -h:
    chmod -h 777 /path/to/dangling-link

    This sets permissions on the symlink itself, regardless of the target's existence.
  4. Alternative syntax:
    On some systems (especially BSD/macOS), --no-dereference works instead of -h:
    chmod --no-dereference 777 /path/to/dangling-link
  5. Batch fix multiple symlinks:
    If you've got a ton of dangling symlinks and need to set them all to some permission, combine with find:
    find /path/to/dir -type l -exec chmod -h 777 {} \;

What to check if it still fails

  • Filesystem type: Some filesystems (like FAT32, exFAT, or network filesystems) don't support symlinks at all, or they simulate them with special files. chmod -h may silently succeed but do nothing. Check with df -T /path/to/link.
  • SELinux or AppArmor: Security modules can block chmod on certain paths. If you get permission denied when using -h, check ausearch -m avc -ts recent on Red Hat/CentOS or dmesg for AppArmor denials on Ubuntu.
  • Read-only filesystem: Obvious but sneaky. If the symlink is on a read-only mount, nothing works. Check mount | grep /path.
  • Symbolic link loop: If the symlink points to another symlink that eventually points back to itself, chmod might hang or fail with 'too many levels of symbolic links'. Use readlink -f /path/to/link to resolve the full chain.

One last thing — don't rely on chmod -h to fix dangling symlinks in production scripts unless you're sure you want to change the link's own permissions (which are ignored by the kernel anyway). The real fix is usually ensuring the target exists. But now you know both roads.

Was this solution helpful?