EC2 SSH "Permission Denied (publickey)": 7 Reasons, Fixed
"Permission denied (publickey)" on an EC2 instance almost never means your key is "wrong" in the way most guides imply — it means SSH already reached your instance and started talking to it, then ran out of ways to prove who you are. The fix is one of seven things: the wrong username for your AMI, the wrong key pair, private key file permissions that are too loose, a private key in the wrong format, a corrupted .pem file, broken permissions on the server's authorized_keys file, or, if you're on Windows, a PuTTY conversion or icacls step nobody told you about. Work through them in that order — cheapest first — and you'll be back in within minutes for six of the seven.
Why this error means the network is fine
Jake runs a phone repair shop, and on a Saturday morning he keeps his parts-ordering system on a t3.small EC2 instance he set up himself two years ago. This particular Saturday, he needed to pull up a supplier's order before a walk-in customer left for a competitor. He typed the same SSH command he always types. It threw back "Permission denied (publickey)." He tried it three more times. Same result. He called Ethan.
🙋♂️ Jake's Reality Check
"My internet's fine, my Wi-Fi is fine, so why is it saying permission denied? Doesn't that mean my whole connection is broken?"
No — it means the opposite. A broken connection gives you "Connection timed out" or "Connection refused." "Permission denied (publickey)" only appears after your computer has already reached the instance over the network, completed the SSH handshake, and started negotiating who you are. The network isn't the suspect. Authentication is.
That distinction matters because it tells you where to stop looking. If you've ever fought with security groups, network ACLs, or route tables for an EC2 instance, that's a different symptom with a different fix — covered here if that's the error you're actually seeing. "Permission denied (publickey)" is purely about the identity you're presenting: the username, the key, and the permissions guarding both ends of that key. There are seven places that identity check can fail, and going through them in the wrong order is how a five-minute problem turns into an afternoon.
Reason 1: You're connecting with the wrong username
This is the single most common cause, and it's the first thing to rule out because it costs nothing to check. EC2 doesn't create a login account matching your local computer's username. Each Amazon Machine Image (AMI — the template your instance was built from) ships with its own default account, and if the part of the SSH command before the @ doesn't match that account, the server will reject your key even if the key itself is perfect.
| AMI used to launch the instance | Default username |
|---|---|
| Amazon Linux / Amazon Linux 2 / 2023 | ec2-user |
| Ubuntu | ubuntu |
| Debian | admin |
| CentOS | centos or ec2-user |
| RHEL | ec2-user or root |
| SUSE | ec2-user or root |
| Fedora | fedora or ec2-user |
| FreeBSD | ec2-user |
| Oracle Linux | ec2-user |
| Bitnami | bitnami |
| Rocky Linux | rocky |
| Anything else (marketplace AMIs, custom AMIs) | Check the AMI provider's listing — there's no universal default. |
If you created a second local user account on the instance yourself after launch, you'd of course use that account's name instead, and its own copy of your public key would need to already be sitting in that account's authorized_keys file. But for a freshly launched instance, the table above is the whole answer.
✅ Why this is the one to check first
It takes ten seconds, requires no file changes, and quietly fixes the majority of "permission denied" reports. The EC2 console's own Connect button, on the SSH client tab, shows the exact example command with the correct username filled in for that specific instance — open it and compare against what you typed.
Reason 2: You're using the wrong key pair for this instance
Each EC2 instance is tied to exactly one key pair, chosen at launch. When the instance boots for the first time, the public half of that key pair is written into the correct account's ~/.ssh/authorized_keys file. From that point on, only the matching private key will authenticate. If you have several .pem files on your computer — one for a personal project, one from work, one you inherited from a teammate — it's easy to point -i at the wrong one and get exactly this error.
To confirm the key pair a running instance expects:
- Open the EC2 console and select the instance.
- On the Details tab, find Key pair name and note it exactly.
- Confirm you're passing the private key file for that same pair to
-i, not a similarly-named file from a different project. - If you're not certain which local
.pemfile corresponds to that key pair name, check your key manager or password vault rather than guessing — guessing burns login attempts and, on some hardened setups, can trigger rate limiting.
⚠️ What this actually breaks
Amazon EC2 never keeps a copy of your private key. It only ever stores the public half. There is no "resend my key" button and no support ticket that gets it back. If this is genuinely the wrong file and the correct one is nowhere on any of your machines, you're not looking at a permissions fix — you're looking at the lost-key recovery procedure near the end of this article.
Reason 3: Your private key file's permissions are too open
OpenSSH refuses to use a private key that other accounts on your own computer could read or modify, and it fails silently into "Permission denied (publickey)" unless you run with verbose logging. On macOS and Linux, if the permissions on the .pem file are looser than owner-only, you'll usually see a much more explicit warning first:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions 0777 for '.ssh/my_private_key.pem' are too open. It is required that your private key files are NOT accessible by others. This private key will be ignored. bad permissions: ignore key: .ssh/my_private_key.pem Permission denied (publickey).
This is what happens most often after you've moved the .pem file between folders, extracted it from a zipped download, or copied it from cloud storage — all of those actions can reset permissions to something wide open. The fix on macOS or Linux is one command:
- Open a terminal in the folder containing your private key file.
- Run
chmod 400 my_private_key.pemto make the file readable by you alone and writable by no one. - Retry the
ssh -icommand exactly as before.
On Windows, permissions work differently — there's no chmod, and the equivalent fix uses icacls or the file's Properties dialog. Because that's a distinct enough process to trip people up on its own, it gets its own full walkthrough in Reason 7 further down.
✅ Why this is the one to use
Some older guides suggest chmod 777 when a permissions error shows up, on the theory that "wide open" can't be a permissions problem. That is precisely backward: 777 is the exact condition OpenSSH refuses to accept. If you've ever run that command on a key file, undo it with chmod 400 before doing anything else.
Reason 4: The private key is in a format your SSH client won't load
There are two distinct format problems here, and they show up with two different error messages, so it's worth telling them apart rather than treating both as "the key is broken."
The OpenSSH-format vs. PEM-format mismatch
If you generated your own key pair with a third-party tool like ssh-keygen and imported the public half to EC2, the private key it produced by default is in OpenSSH's own format, not the PEM format EC2's own key generator uses. Some SSH clients handle this transparently; some throw Private key must begin with "-----BEGIN RSA PRIVATE KEY-----" instead of a clean "permission denied," which at least tells you exactly what's wrong. The fix is to regenerate the key explicitly in PEM format:
ssh-keygen -m PEM
DSA keys and the wrong algorithm entirely
Amazon EC2 does not accept DSA key pairs. If your key generator was set to DSA rather than RSA or ED25519, no amount of permission-fixing will help — the server rejects the algorithm outright. Regenerate with ssh-keygen -t rsa or ssh-keygen -t ed25519, then import the new public key to your account, since RSA and ED25519 are the two types EC2 actually recognizes (ED25519 keys, however, aren't supported for Windows instances, so stick with RSA there).
Reason 5: The .pem file itself got altered
A .pem file is plain text, and that's exactly the problem — it's tempting to open it in a text editor "just to look," and a stray extra line break, trailing whitespace, or a save that quietly changed line endings from Unix-style to Windows-style is enough to invalidate the whole key even though it still looks intact to a human eye. If you get unable to load key ... Expecting: ANY PRIVATE KEY, that's the file itself failing to parse, not an authentication rejection.
There's no safe way to hand-repair a key file once this happens. The vendor-documented path is to treat the file as unrecoverable: generate a fresh key pair, add the new public key to the instance while you still have another way in (covered in the workarounds section), and retire the damaged file. Trying to patch whitespace back into a corrupted PEM file by eye is a good way to spend an hour producing a second broken file.
Reason 6: Permissions on the instance's own authorized_keys changed
This is the counterintuitive one, and it's exactly what was happening to Jake. If you were connecting fine for months and the error appeared with nothing on your end having changed — same computer, same key file, same command — the cause almost certainly lives on the instance, not on your desk. SSH enforces strict permissions on the server side too: the home directory, the .ssh folder inside it, and the authorized_keys file must each be writable only by their owner, or the SSH daemon ignores the key entirely and denies you, again without a helpful error.
A configuration management tool, a botched permissions script, a shared deployment user, or even an over-broad chmod -R run against /home during routine maintenance can loosen those permissions without anyone noticing until the next login attempt fails. The target permissions are: the home directory at 0755, the .ssh folder at 0700, and authorized_keys at 0600, all owned by the account you're logging into.
Fixing this requires getting onto the instance by some route other than the broken SSH login, since that's the very thing that's failing. If you still have another way in — a Session Manager connection, a different working key, or the EC2 serial console — run:
sudo chown root:root /home sudo chmod 755 /home sudo chown ec2-user:ec2-user /home/ec2-user -R sudo chmod 700 /home/ec2-user /home/ec2-user/.ssh sudo chmod 600 /home/ec2-user/.ssh/authorized_keys
Substitute your actual username for ec2-user throughout. If you have no other way onto the instance at all, this is exactly the situation the EBS-volume-swap procedure near the end of this article was built for — it's more work, but it does not require you to have any existing SSH access.
Reason 7: You're on Windows, and it's not the key at all
Windows handles two things differently enough from macOS and Linux that they deserve their own reason rather than a footnote under the others.
Using the built-in OpenSSH client (PowerShell or Command Prompt)
Windows 10 and 11 both ship an OpenSSH client, and it enforces the same "not accessible by others" rule as macOS and Linux, but chmod doesn't exist on Windows — the equivalent tool is icacls, or the Properties dialog if you'd rather click through it. From a command prompt:
- Navigate to the folder containing your
.pemfile. - Run
icacls.exe $path /reset(replacing$pathwith the file path) to strip out any existing custom permissions. - Run
icacls.exe $path /GRANT:R "$($env:USERNAME):(R)"to grant read-only access to your own account and nobody else. - Run
icacls.exe $path /inheritance:rto stop the file from inheriting broader permissions from its parent folder.
If you'd rather do this through the interface: right-click the .pem file, choose Properties, open the Security tab, choose Advanced, confirm you're the file's owner, select Disable inheritance and remove all inherited permissions, then add your own username back with read-only access.
Using PuTTY instead
PuTTY does not read .pem files at all — it only understands its own .ppk format, and trying to load a .pem directly is a guaranteed "Server refused our key" or "No supported authentication methods available." Convert it first, using PuTTYgen, which comes bundled with the PuTTY installer:
- Open PuTTYgen and under Type of key to generate, choose RSA (or SSH-2 RSA on older versions).
- Choose Load, switch the file filter to show all file types, and select your
.pemfile. - Once PuTTYgen confirms the import succeeded, choose Save private key, accept the warning about saving without a passphrase, and give it the same name as your key pair with a
.ppkextension. - In PuTTY itself, load that
.ppkfile under Connection > SSH > Auth > Credentials, and enter the correct username (from the table in Reason 1) in the Host Name field asusername@public-dns-or-ip.
🙋♂️ Jake's Reality Check
"I've used the same PuTTY setup for years without converting anything. Why would it suddenly matter now?"
Ethan's take is: "It doesn't suddenly matter — you converted it once, years ago, and forgot you did. The conversion only needs to happen the first time you use a given key pair with PuTTY. If PuTTY is failing on a key pair you've genuinely never loaded into it before, that's the missing step."
Matching your ssh -v output to the right reason
If none of the above feels obviously like your situation, add -v (or -vvv for maximum detail) to your SSH command and read the output before guessing further:
ssh -vvv -i path/key-pair-name.pem instance-user-name@your-instance-address
| What you see in the debug output | Most likely reason |
|---|---|
Authentications that can continue: publickey then No more authentication methods to try | The key offered doesn't match what's in authorized_keys — Reason 2 or Reason 6 |
bad permissions: ignore key | Reason 3 — the local private key file's own permissions |
unable to load key ... Expecting: ANY PRIVATE KEY | Reason 5 — the file has been altered or is missing content |
Private key must begin with "-----BEGIN RSA PRIVATE KEY-----" | Reason 4 — OpenSSH-format key, needs ssh-keygen -m PEM |
| Connects and authenticates, then the shell immediately rejects the login | Reason 1 — wrong username for a valid key |
If you need in right now: EC2 Instance Connect and Session Manager
Before touching the volume-swap procedure in the next section, check whether either of these two AWS-native tools gets you onto the instance without needing the original key at all. Both need to have been enabled ahead of time or be supported by the AMI, so this is worth knowing about before you're in an emergency, not just during one.
EC2 Instance Connect pushes a temporary SSH public key to the instance's metadata for 60 seconds, which is long enough to authenticate once with a brand-new key pair you generate on the spot — useful precisely when your existing key is the thing that's broken. It comes preinstalled on newer Amazon Linux and Ubuntu AMIs. The flow:
- Generate a fresh key pair locally:
ssh-keygen -t rsa -f mynew_key. - Push the public half to the instance:
aws ec2-instance-connect send-ssh-public-key --instance-id i-1234567890abcdef0 --instance-os-user ec2-user --availability-zone us-east-2b --ssh-public-key file://mynew_key.pub. - Connect within 60 seconds, before the temporary key is removed:
ssh -o "IdentitiesOnly=yes" -i mynew_key ec2-user@your-instance-address.
One quirk worth knowing about in advance: on Ubuntu 20.x specifically, if your SSH daemon configuration already defines its own AuthorizedKeysCommand for something else, EC2 Instance Connect's push can fail even though everything looks correctly installed — that's the "Ubuntu 20.x only" caveat vendor documentation calls out separately from the more common causes.
AWS Systems Manager Session Manager takes a different approach entirely: it opens an interactive shell through the SSM agent rather than through SSH, so a broken key or a broken authorized_keys file is irrelevant to it. It does need the SSM agent running on the instance and the right IAM permissions attached beforehand, which is why it's worth setting up before you need it rather than during a lockout.
When nothing above works: recovering access without the original key
This is the most drastic fix on this list, and it's also the one guaranteed to work for an EBS-backed instance regardless of which of the seven reasons caused the lockout — because it never relies on SSH working at all. The idea: stop the instance, detach its root volume, attach that volume to a second, healthy instance as a data disk, edit the broken authorized_keys file directly from there, then move the volume back.
- Note the original instance's instance ID, AMI ID, Availability Zone, root device name, and root volume ID from the console before doing anything else.
- Stop the original instance. (This step only works for EBS-backed root volumes — instance-store-backed instances cannot be recovered this way, and losing the key there means losing access permanently.)
- Launch a small temporary instance in the same Availability Zone, using a similar AMI, with a key pair you do have.
- Detach the root volume from the original (now-stopped) instance and attach it to the temporary instance as a secondary volume.
- On the temporary instance, mount the attached volume and either add your working public key to the volume's
authorized_keysfile, or correct its permissions if that was the actual cause. - Unmount, detach the volume from the temporary instance, and reattach it to the original instance at its original device name (typically
/dev/xvda— using a different device name will prevent the instance from starting). - Start the original instance and connect using either your existing key (if you only fixed permissions) or the new key pair you added.
- Terminate the temporary instance once you've confirmed access, if you no longer need it.
⚠️ What we cannot do for you
If the root volume is instance-store rather than EBS-backed, none of this works, and there is no supported path back in without the original private key. Check Storage > Root device type on the instance before you count on this procedure — it's worth knowing which type you're running before you ever hit a lockout, not after.
Back at the shop, Jake's situation turned out to be Reason 6: a script a contractor had run months earlier to "clean up" file permissions across the fleet had quietly loosened /home on that one instance, and it only surfaced the next time SSH tried to authenticate him. Ethan's opinion on that, once they'd fixed it: "the permissions error was never really about your key. Your key was fine the whole time — it's usually the instance that changes, not you."
Frequently asked questions
What does "Permission denied (publickey)" actually mean?
It means SSH successfully reached your instance and started the authentication handshake, but every key you offered was rejected by the server. It's specifically about identity, not network reachability — the connection itself worked.
Why does this happen even when I'm sure I'm using the right key?
The three next-most-likely causes after a mismatched key are a wrong username, private key file permissions that are too open on your own machine, and permissions on the instance's own authorized_keys file having changed since you last connected successfully.
How do I fix "Permission denied (publickey)" on Windows?
If you're using the built-in OpenSSH client, reset the .pem file's permissions with icacls.exe so only your account can read it. If you're using PuTTY, convert the .pem to a .ppk file with PuTTYgen first — PuTTY cannot read .pem files directly.
Can I fix this without losing data on the instance?
Yes. None of the seven fixes above touch the instance's data. Even the EBS volume-swap recovery procedure only edits the authorized_keys file on the existing root volume; it doesn't delete or recreate anything.
Why did SSH work yesterday and not today?
If nothing changed on your computer, the change happened on the server. The most common cause is permissions on the home directory, .ssh folder, or authorized_keys file getting loosened by a maintenance script, a configuration management tool, or an accidental broad chmod.
Is chmod 777 ever the right fix for a .pem file?
No. OpenSSH specifically refuses to use a private key with permissions that open, and warns that the key is being ignored. The correct permission for a private key file is 400 (owner read-only).
What username should I use to connect?
It depends entirely on the AMI: ec2-user for Amazon Linux, ubuntu for Ubuntu, admin for Debian, centos for CentOS, and so on. The EC2 console's Connect page shows the exact username for your specific instance.
How do I know which key pair my instance uses?
Open the instance in the EC2 console and check Key pair name on the Details tab. That's the name of the key pair whose matching private key file you need.
Can I add a second SSH key to an existing instance?
Yes, once you're logged in through some method, you can append additional public keys to that account's authorized_keys file, which lets multiple people or multiple key pairs access the same account going forward.
What if I don't have the original .pem file at all?
For an EBS-backed instance, the volume-swap recovery procedure lets you add a new key without the original file. For an instance-store-backed instance, there is no way back in without the original private key, since the root volume can't be detached and mounted elsewhere.
Does this happen with EC2 Instance Connect too?
It can, though the causes differ slightly. On Ubuntu 20.x specifically, a pre-existing custom AuthorizedKeysCommand setting in the SSH daemon configuration can cause EC2 Instance Connect's temporary key push to fail even when the feature is correctly installed.
Why do I see "Authentications that can continue: publickey" in the debug output?
That line means the server tried every key you offered and rejected all of them, then had no other authentication method left to fall back on. It generally points to a key mismatch rather than a permissions or format issue.
Can a security group cause "Permission denied (publickey)"?
No. A security group blocking traffic produces a connection timeout, not a permission denial, because the connection never reaches far enough to start authenticating. If security groups are genuinely your issue, that's a different error message entirely.
What's the difference between "Server refused our key" and "Permission denied (publickey)"?
They're PuTTY's and OpenSSH's respective wording for essentially the same underlying rejection. "Server refused our key" is what PuTTY shows; check the same causes — username, key match, and for PuTTY specifically, whether the .pem was actually converted to .ppk.
Do I need to convert my .pem file for PuTTY?
Yes, always, the first time you use a given key pair with PuTTY. PuTTY does not natively read the PEM format that EC2 generates; PuTTYgen converts it to the .ppk format PuTTY requires.
Will reinstalling OpenSSH on Windows fix this?
Almost never. The underlying causes are the same seven reasons covered above — username, key match, file permissions, key format, file corruption, server-side permissions, or a missed PuTTY conversion — not a broken OpenSSH installation. Reinstalling the client doesn't touch any of those.
- EC2 connection timed out, refused, or denied: what each error actually means
If your error is a timeout rather than "permission denied," the cause and the fix are both different — start there instead. - What is Amazon EC2? Cloud computing explained
For anyone still getting oriented on what an instance, an AMI, and a key pair actually are before troubleshooting them.
Revision note. Written August 2026, covering current EC2 Linux AMIs and the OpenSSH and PuTTY clients on Windows 11 and 10. This will need a revisit if AWS changes the default authentication flow for EC2 Instance Connect or introduces a new key type. If you're reading this at 11 p.m. with a locked-out instance and a deadline, take a breath — every one of these seven causes has a fix that doesn't involve rebuilding anything.