Load key: "invalid format" or "error in libcrypto"

SSH read the key file and could not parse it as a private key. On Linux builds with OpenSSL the same problem usually reads error in libcrypto. The common causes are Windows line endings, a missing newline at the end, line breaks lost in a CI variable, a .pub or .ppk file used by mistake, and a truncated copy. Test the file with ssh-keygen -y -f keyfile, then fix it or copy it again.

Updated . Every damaged file in the table was made from a throwaway key and tested with OpenSSH 10.3 on macOS (LibreSSL) and OpenSSH 10.0 on Debian 13 (OpenSSL).

What you see

Load key "/home/user/.ssh/id_ed25519": invalid format
user@server: Permission denied (publickey).

On many Linux systems the same damaged file gives:

Load key "/home/user/.ssh/id_ed25519": error in libcrypto

In our tests the same file gave invalid format on macOS and error in libcrypto on Debian. So treat them as one problem. A wrong passphrase looks different: incorrect passphrase supplied to decrypt private key.

SSH does not stop here. It continues with other keys and passwords, so the login may fail later or even succeed with something else.

Test the file without connecting

ssh-keygen -y -f ~/.ssh/id_ed25519

A good key prints its public key, or asks for a passphrase and then prints it. A bad one prints the same Load key error. file is not a reliable test here: it still reports OpenSSH private key for a damaged file.

Check what is wrong with it

In a healthy file these print only the header and footer lines. A damaged file with everything on one line would show the whole key, so do not run them in a CI log or on a shared screen:

head -1 ~/.ssh/id_ed25519
tail -1 ~/.ssh/id_ed25519
tail -c 1 ~/.ssh/id_ed25519 | xxd
grep -c $'\r' ~/.ssh/id_ed25519
You seeCauseFix
grep -c prints more than 0Windows line endings, from a Windows editor or a copy through Windowstr -d '\r' < key > key.fixed
xxd shows 2d, not 0aNo newline after the END lineecho >> key
Starts with ssh-ed25519 AAAA or ssh-rsa AAAAThis is the public keyUse the file without .pub
Starts with PuTTY-User-Key-FilePPK formatConvert it, see below
First line is not -----BEGIN ..., or last line is not -----END ...Part of the file is missingCopy it again from the source
Everything on one line, with spacesLine breaks were lostSee CI below
Empty fileThe copy failedCopy it again from the source
file key reports UTF-16Saved by PowerShell 5 > or an editor set to Unicodeiconv -f UTF-16 -t UTF-8 key > key.fixed

The strict checks on line endings and the final newline apply to the newer format, the one starting with -----BEGIN OPENSSH PRIVATE KEY-----. An older -----BEGIN RSA PRIVATE KEY----- file with the same damage still loaded in our test.

After writing a fixed copy, set its permissions and test it. Without this, SSH can refuse it for a different reason, see unprotected private key file:

chmod 600 key.fixed
ssh-keygen -y -f key.fixed

Keys in CI variables

This is a very common source of the error. Without quotes, the shell turns the line breaks into spaces. And printf '%s' adds no newline, so a variable that has no final newline produces a bad file. Both of these failed:

echo $SSH_KEY > key
printf '%s' "$SSH_KEY" > key

This works, as long as the variable holds the complete key with its line breaks:

printf '%s\n' "$SSH_KEY" > key
chmod 600 key
ssh-keygen -y -f key > /dev/null

Run the last line as an early step in the job, and it fails with a clear error. Mind what your CI system does with multi-line values. Some keep them only when stored as files, and some store base64 instead.

PPK keys

OpenSSH does not read .ppk files. Convert them with the PPK key generator, or on Linux and macOS:

puttygen key.ppk -O private-openssh -o key
chmod 600 key

Details in Convert a PPK key to OpenSSH.

Wrong file in your config

If you never meant to use this key, see where it comes from:

ssh -G server | grep '^identityfile '

-i key.pub and IdentityFile key.pub are a common mistake. SSH offers the public key, the server accepts it, and then loading it as the private key fails, often with bad permissions because .pub files are readable by everyone. Point them at the private file.

If the key really is truncated and you have no other copy, it cannot be repaired. Generate a new key, install it, and remove the old public key from your servers.

To get the public key back from a working private key, see how to get the public key from a private key.

Questions

What is the difference between invalid format and error in libcrypto?

Usually none. The same damaged file gives invalid format with LibreSSL builds, as on macOS, and error in libcrypto with OpenSSL builds on Linux.

Can a key with invalid format be repaired?

Often, when only the line endings or the final newline are wrong. A truncated key cannot be repaired: generate a new one and replace the public key on your servers.

Why does my key work locally but fail in CI?

The CI variable usually lost its line breaks or its final newline. Write it to the file with quotes and a final newline, then test it with ssh-keygen -y -f.

Sources

More in Error messages

All guides