Search tools

Developer guides

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.

Read next