How to fix the SSH "unprotected private key file" error
SSH refuses to use a private key that other people could read. Here is exactly which permissions it wants, and how to set them on Linux, macOS, Windows and WSL.
You try to connect and SSH stops before it even reaches the server:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/sam/.ssh/id_ed25519' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/home/sam/.ssh/id_ed25519": bad permissions
It is not a bug. A private key works like a password for every server that trusts it, so SSH refuses to use one that other users on your computer could read. The fix is one command.
The fix on Linux and macOS
Make the key readable and writable by you alone:
chmod 600 ~/.ssh/id_ed25519
Swap in the name of your own key, such as id_rsa, or the .pem file a cloud provider
gave you. 400 works too, and it is what AWS suggests for downloaded keys: it makes the
file read only even for you, which guards against accidental edits. See
what chmod 600 means and
what chmod 400 means for the details.
Then tighten the folder around it:
chmod 700 ~/.ssh
The permissions SSH expects
| Path | Mode | Why |
|---|---|---|
~/.ssh |
700 | Only you can list or enter it |
| Private keys | 600 or 400 | Only you can read them |
Public keys (.pub) |
644 | Safe to share, so anyone may read them |
authorized_keys |
600 | On servers; 644 is also accepted |
config |
600 | It can contain host names and user names |
| Your home directory | 755 or stricter | It must not be writable by others |
That last row catches people out on servers. With its default StrictModes setting, the
SSH server ignores your authorized_keys file if your home directory or .ssh folder is
writable by other users, and key login quietly falls back to asking for a password.
chmod go-w ~ fixes it.
Check that you own the files as well. A key copied with sudo can end up owned by root,
and then not even 600 helps: sudo chown $USER:$USER ~/.ssh/id_ed25519.
On Windows
Windows has no chmod, but OpenSSH on Windows applies the same rule through file permissions: the key must not be readable by any account except yours, the Administrators group and SYSTEM. Keys copied from somewhere else often inherit permissions from their folder that let other users in. Fix it in PowerShell:
icacls $env:USERPROFILE\.ssh\id_ed25519 /inheritance:r
icacls $env:USERPROFILE\.ssh\id_ed25519 /grant:r "$($env:USERNAME):(R)"
The first line removes the inherited permissions and the second gives your own account read access. You can do the same through the file’s Properties: open Security, then Advanced, turn off inheritance and remove every entry except your own user.
On WSL
Files under /mnt/c live on the Windows drive, and by default WSL shows them as open to
everyone and ignores chmod on them. Copy the key into your Linux home directory instead,
and set the permissions there:
mkdir -p ~/.ssh && cp /mnt/c/Users/you/.ssh/id_ed25519 ~/.ssh/
chmod 700 ~/.ssh && chmod 600 ~/.ssh/id_ed25519
Why SSH is this strict
Anyone who can read your private key can log in as you on every server that trusts it, and nothing on the server can tell the difference. On a shared machine, 644 means every other user can copy it. SSH could print a warning and carry on, but a key that has been readable may already be compromised, so it refuses outright. The error costs you a minute; the alternative could cost a lot more.
If a key has sat on a shared machine with open permissions for a while, fixing the mode is not enough on its own. Generate a new key, add it to your servers and remove the old one. Everything else about how permissions work is in the guide to Linux file permissions.