Skip to content
Launch offerNew accounts: we double your first deposit of $100 or more, up to $250 bonus.Claim my bonus
LiteKeep
Sign inDeploy a server

Troubleshooting tutorial, 2026

“Permission denied (publickey)”? Let the server tell you why.

Most fixes for this error are guesses in a list. We broke a real server twelve different ways and wrote down exactly what each one looks like, on both ends.

  • 15 min read
  • 14 chapters
  • Updated

What you see, every time

Permission denied (publickey).

What the server knows

  • Invalid user deploy
  • bad ownership or modes for directory ~/.ssh
  • bad ownership or modes for file authorized_keys
  • not listed in AllowUsers
  • maximum authentication attempts exceeded
  • no mutual signature algorithm

The short answer

The server refused every key you offered, and that message is the same for every cause. The reason is written in the server’s log: run sudo journalctl -u ssh -n 50 on the server (through the web console if you’re locked out; every LiteKeep server has one).

The usual culprits: the wrong user name, your key missing from ~/.ssh/authorized_keys, permissions on ~/.ssh (use 700) or the file (600), too many keys offered, or a file saved in the wrong format on Windows. Paste your error into our free decoder below.

Here’s why this error is so maddening.

We set up a test server and caused twelve different login failures: a wrong user, a wrong key, bad permissions, a file saved by PowerShell, an old RSA signature and more. The message on our screen was identical every time (save for the list in brackets, which we’ll decode).

The good news? The server knows exactly what went wrong, and for most causes it writes it down. Once you know where to look, most of these take a minute to fix.

Most fixes online skip that step, and some even tell you to switch password logins back on. We’ll show you the log line for every cause instead, so you fix the real problem once.

In this guide you’ll learn

  • A free error decoder: paste the message, get the cause and the fix
  • What the brackets mean: (publickey), (publickey,password) and ()
  • Where the real reason is: the server log and ssh -v
  • 12 causes we reproduced, each with its exact log line
  • The Windows traps: file encodings and key permissions
  • GitHub, default users and old RSA keys, and fixes that make things worse

Chapter 1

The short answer

The same words appear in very different places. Find yours first:

Where are you seeing it?
You seeIt meansGo to
user@your-server: Permission denied (publickey)Your server rejected every key you offeredRead the server log
[email protected]: Permission denied (publickey)GitHub doesn’t recognise your keyGitHub fixes
Permission denied on a brand-new serverOften the wrong default user nameDefault users
WARNING: UNPROTECTED PRIVATE KEY FILE!Your PC refused to use the keyWindows fixes
Too many authentication failuresYour client offered too many keysAll causes

Chapter 2

Decode your error

Paste the error from your terminal, the output of ssh -v, or lines from the server’s log. The decoder matches them against the messages we recorded while reproducing each cause. It runs only in your browser.

Try an example:

Paste something on the left. The more lines, the better: the server log usually names the cause.

Just the one line, Permission denied (publickey)? The decoder will tell you that’s not enough to go on. The next two chapters show how to get the lines that are.

Chapter 3

What the words in brackets mean

The part in brackets isn’t decoration. It’s the list of login methods the server still allows after rejecting yours. We changed the server’s settings and watched it change:

The same failed key, three server settings
Client showsServer allowsWhat it tells you
Permission denied (publickey).Keys onlyNormal for a hardened server. Your key wasn’t accepted.
Permission denied (publickey,password).Keys and passwordsYour key failed; the server would also take a password.
Permission denied ().Nothing at allKey login is switched off on the server (PubkeyAuthentication no).

Empty brackets are rare and serious: no key will ever work until someone fixes the server config, usually through the server’s web console.

Chapter 4

Read the server’s log

On Ubuntu the SSH service is called ssh, and its log lives in the journal. Read it, or follow it live:

sudo journalctl -u ssh -n 50          # the last 50 lines
sudo journalctl -fu ssh                # follow live, then try to log in again

Older systems and many other distributions also write to /var/log/auth.log. Can’t log in to read it? On LiteKeep, open the web console on your server’s page and read it there. Next time, keep a working session open while you change anything.

Lines worth looking for

Log lines we captured, and what they mean
Log lineCause
Invalid user deploy from …That user doesn’t exist on the server
Authentication refused: bad ownership or modes for file …/authorized_keysauthorized_keys is writable by others
Authentication refused: bad ownership or modes for directory …~/.ssh or your home folder is writable by others
User root from … not allowed because not listed in AllowUsersThe server config blocks that user
maximum authentication attempts exceeded for …Too many keys offered
Connection closed by authenticating user … [preauth]A key was tried and refused; the log doesn’t say why (see below)

When the log says nothing useful

For a wrong key, a broken file or an old RSA signature, the default log only says Connection closed … [preauth]. Raise the detail with LogLevel VERBOSE and the server names the key it refused:

Failed publickey for root from 203.0.113.5 port 51034 ssh2: ED25519 SHA256:qqhU29HIyn/qAl0/yqZAa6sOXDf2OkegYnr4KJQ7OPM
Our test server at LogLevel VERBOSE, with a key the server couldn't read. Compare that SHA256 value with your key's fingerprint.

Then compare fingerprints: run ssh-keygen -lf ~/.ssh/id_ed25519.pub on your PC and ssh-keygen -lf ~/.ssh/authorized_keys on the server. If the server’s list doesn’t include yours, the key isn’t installed. If the command fails outright, the file is damaged (chapter 7).

Chapter 5

Read your side with ssh -v

Add -v to your command and look for three kinds of lines:

debug1: Authentications that can continue: publickey
debug1: Offering public key: C:\Users\you\.ssh\id_ed25519 ED25519 SHA256:EMQ9pBYv… explicit
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
[email protected]: Permission denied (publickey).
Trimmed from our run with a key the server didn't have. 'explicit' means it came from -i or IdentityFile.
  • Offering public key: which key it tried. Not the one you expected? Point at the right one with -i, or add IdentityFile to your config.
  • No such identity / no key lines at all: SSH found no key. Check the file name and path.
  • no mutual signature algorithm: an old RSA signature (chapter 9).

Chapter 6

The 12 causes we reproduced

Each row was caused on purpose on our test server, then fixed. Start with the row whose log line matches yours.

Twelve causes, as we saw them (Windows 11 OpenSSH 9.5 client, Ubuntu 24.04 OpenSSH 9.6 server)
CauseServer log (default level)Fix
Wrong user nameInvalid user …Use the user the key was added for
Key not in authorized_keysConnection closed … [preauth]Add the .pub line for that user
authorized_keys writable by everyone (666)bad ownership or modes for filechmod 600 ~/.ssh/authorized_keys
~/.ssh writable by everyone (777)bad ownership or modes for directory …/.sshchmod 700 ~/.ssh
Home folder writable by everyone (777)bad ownership or modes for directory /home/…chmod 755 ~
File saved as UTF-8 with BOMConnection closed … [preauth]Strip the BOM (chapter 7)
File saved as UTF-16Connection closed … [preauth]Convert with iconv (chapter 7)
User not in AllowUsersnot allowed because not listed in AllowUsersAdd the user, sshd -t, reload
Key login switched offConnection closed … (client shows “()”)PubkeyAuthentication yes, reload
Too many keys offeredmaximum authentication attempts exceededIdentitiesOnly yes and -i
RSA key signed with old SHA-1Connection closed … [preauth]New Ed25519 key, or update the client
Private key readable by others (Windows)Nothing: the client never sends iticacls fix (chapter 10)

Two things that did not break login

Plenty of guides blame these. In our test, both still worked:

MythWindows line endings (CRLF) in authorized_keys break it.

Fact

Our server accepted a file with CRLF endings. The encoding is what breaks it: a byte order mark or UTF-16 (chapter 7).

MythAny group-writable permission breaks it.

Fact

authorized_keys at 664 and a home folder at 775 both still worked, because the group contained only the owner. World-writable (666, 777) is what the server refuses.

Chapter 7

The Windows file-format trap

This one fools experienced people. You paste your key into authorized_keys, it looks perfect, and it never works. The cause is invisible: how the file was saved.

If you build the file on Windows and upload it, PowerShell may have saved it with a hidden byte order mark, or as UTF-16. Windows PowerShell 5.1’s Out-File -Encoding utf8 adds the mark, and -Encoding unicode writes UTF-16. In our test, both were rejected, and the server’s normal log said nothing.

How to tell

$ ssh-keygen -lf good.pub
256 SHA256:qqhU29HIyn/qAl0/yqZAa6sOXDf2OkegYnr4KJQ7OPM litekeep-test (ED25519)
$ ssh-keygen -lf ak_bom
ak_bom is not a public key file.
$ file -b ak_bom
Unicode text, UTF-8 (with BOM) text, with CRLF line terminators
$ file -b ak_utf16le
Unicode text, UTF-16, little-endian text, with CRLF line terminators
Our three test files: a good one, one with a BOM, one in UTF-16. ssh-keygen can't read the broken ones, and file names the problem.

How to fix it

Both repairs worked on copies of our broken files:

# UTF-8 with a BOM: remove the 3 hidden bytes
sed -i '1s/^\xEF\xBB\xBF//' ~/.ssh/authorized_keys

# UTF-16: convert to UTF-8
iconv -f UTF-16 -t UTF-8 ~/.ssh/authorized_keys > /tmp/ak && mv /tmp/ak ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

# Confirm: it should print your key's fingerprint
ssh-keygen -lf ~/.ssh/authorized_keys

Chapter 8

When the server’s config is the cause

Sometimes the key is fine and the server is set up to refuse it. Three settings matter most: PubkeyAuthentication, AuthorizedKeysFile and AllowUsers.

Your edit may be ignored

Modern Ubuntu reads extra files from /etc/ssh/sshd_config.d/, and settings there override the main file. The reason: for each setting, the first value read wins, and the drop-in folder is read near the top.

Some provider images of Ubuntu ship their own drop-ins, such as a 00- and a 99- file that both set PasswordAuthentication yes and PermitRootLogin yes. Change those settings in /etc/ssh/sshd_config and nothing happens. That’s why the next command matters.

See what the server really uses

sudo sshd -T | grep -Ei "^(pubkeyauthentication|passwordauthentication|permitrootlogin|authorizedkeysfile|allowusers) "
ls /etc/ssh/sshd_config.d/

sshd -T prints the settings after every file is read. That’s the truth, whatever the files look like.

Change it safely

  1. Keep a working session openHow to check: Change SSH from a session that is already logged in, and don’t close it until a new one works.
  2. Edit the file that winsHow to check: A drop-in whose name sorts first, or the image’s own file. Then check with sshd -T.
  3. Test the configHow to check: sudo sshd -t prints nothing when the config is valid. Run it before every restart.
  4. Reload, don’t rebootHow to check: sudo systemctl reload ssh. On Ubuntu 22.10 and later SSH can also be started by a socket; check with systemctl status ssh.socket if a port change doesn’t take.

Chapter 9

Old RSA keys and old clients

In 2021, OpenSSH 8.8 stopped accepting one kind of RSA signature. It disables RSA signatures using the SHA-1 hash by default.

RSA keys themselves still work: in our test, a 3072-bit RSA key logged in fine with a modern client. What fails is an old client (old PuTTY, libraries, some CI tools) that can only sign the old way. We forced our client to do that, and ssh -v said:

debug1: Offering public key: C:\Users\you\.ssh\id_rsa RSA SHA256:qIRn50tc… explicit
debug1: send_pubkey_test: no mutual signature algorithm
debug1: No more authentication methods to try.
[email protected]: Permission denied (publickey).
Our RSA key, with the client limited to the legacy ssh-rsa signature. The server is modern, so there's no algorithm they share.
  • Best fix: make an Ed25519 key with ssh-keygen -t ed25519 and add it to the server.
  • Or update the client so it signs RSA with SHA-256 or SHA-512, which OpenSSH has supported since version 7.2.
  • DSA keys are finished: OpenSSH removed DSA support in version 10.0.

Chapter 10

Windows: the key your PC won’t use

On Windows, OpenSSH refuses a private key that other accounts can read. It never even reaches the server, so the server log stays empty.

WARNING: UNPROTECTED PRIVATE KEY FILE!
Permissions for 'C:\Users\you\.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.
[email protected]: Permission denied (publickey).
Our real warning; path, user and address replaced with examples.

These two lines fixed it in our test:

icacls "$HOME\.ssh\id_ed25519" /inheritance:r
icacls "$HOME\.ssh\id_ed25519" /grant:r "${env:USERNAME}:R"

Also on Windows: ssh-agent is disabled by default, so a key you added with ssh-add on another machine isn’t loaded here. Our Windows tutorial covers turning it on.

Chapter 11

[email protected]: Permission denied (publickey)

When Git says it, the server refusing you is GitHub, not yours. The checks, in order:

ssh -T [email protected]              # should greet you by your GitHub user name
ssh -vT [email protected]             # if not: which key was offered?
ssh-add -l -E sha256                # which keys the agent holds
git remote -v                       # the remote must start with [email protected]:
  • Always connect as git, never your own name: [email protected].
  • Add the public key to your account: Settings, SSH and GPG keys. Compare its fingerprint with ssh-add -l -E sha256.
  • Using sudo? sudo git push runs as root, with root’s keys, not yours. Drop the sudo.
  • HTTPS remote? Then it isn’t using SSH at all. Switch with git remote set-url origin [email protected]:user/repo.git.

Chapter 12

New servers: the default user name

Many cloud images don’t let you log in as root, and each has its own default user. Log in as the wrong one and the key is refused, however right it is.

Common default users on cloud images
ImageUser
Ubuntu cloud imagesubuntu
Debian cloud imagesdebian or admin
Rocky Linuxrocky
Fedorafedora
Bitnami imagesbitnami

On LiteKeep, a new server starts with root. Add your public key when you deploy, log in as root@your-server-ip, and it works first time. Your welcome email and the server’s page show the details.

Chapter 13

Fixes that make things worse

You’ll see these suggested all over the web. Each one hides the problem and opens a new one.

MythTurn PasswordAuthentication back on.

Fact

That gets you in by bypassing the key, and reopens the door to password guessing. Our own server saw more than 14,000 attempts in three days. Fix the key, keep passwords off.

Mythchmod 777 the .ssh folder so SSH can read it.

Fact

The opposite: the server refuses world-writable folders. We tested it. Use 700 and 600.

MythSet StrictModes no.

Fact

It switches off the permission check for every user, so anyone who can write your files can add their own key.

MythRun setenforce 0 on RHEL or Fedora.

Fact

That turns SELinux off. If SELinux labels are the issue, restorecon -Rv ~/.ssh fixes the labels and keeps the protection.

Chapter 14

Locked out completely?

If no key works and passwords are off, you need a way in that doesn’t use SSH.

  • The web console: a browser window onto the server’s screen. Every LiteKeep server has one on its page in your account. Log in there, read the log, fix the file.
  • A snapshot: took one before the change? Roll back to it from the server’s Snapshots tab.
  • Reinstall as a last resort, with your key added, then restore from backup.

Next time, change SSH the way our VPS security guide does it: a second session kept open, sshd -t before every reload, and a test login before you close anything.

Now it’s your move

“Permission denied (publickey)” is one sentence covering a dozen problems. The server almost always knows which one.

Read its log, match the line, fix that one thing. And if you’re setting up keys for the first time on Windows, our step-by-step tutorial avoids most of these before they happen.

Tired of servers you can’t get back into? Deploy a Lite 2: your key goes in at deploy, and the web console is one click away if SSH ever refuses you.