How to fix key_load_public: invalid format in SSH

SSHINTERMEDIATEMEDIUMUpdated May 28, 2026· 423 views

OpenSSH fails to parse an SSH key file with "key_load_public: invalid format". Usually caused by PuTTY-format keys, BOM/CRLF corruption, or a wrong key format. Convert or regenerate the key in OpenSSH format to fix it.

Quick fix

Fixes key_load_public: invalid format

head -1 ~/.ssh/id_rsa.pub
  1. Verify the key file format
  2. Regenerate public key from private key
  3. Remove a UTF-8 BOM if present
  4. Fix line endings on Windows keys
ssh — error
head -1 ~/.ssh/id_rsa.pub
key_load_public: invalid format

What this error means

OpenSSH relies on strict key file formats. When the SSH client or server attempts to load a public key using the `key_load_public()` function, it validates the file structure against expected formats. If the key file contains unexpected bytes, incorrect line endings, a UTF-8 BOM marker, or uses an incompatible format (such as PuTTY's RFC 4716 format with a `---- BEGIN SSH2 PUBLIC KEY ----` header instead of the single-line OpenSSH format), the parser rejects it with "invalid format". The error can appear as a non-fatal warning (SSH still works because the corresponding private key in the agent or on disk is usable) or as a fatal error (SSH fails), depending on whether a usable key is found through another path.

Typical symptoms

  • SSH warning message appears but connection may still work: 'load pubkey "~/.ssh/id_rsa": invalid format'
  • SSH client refuses to load the public key file during authentication
  • SSH command fails with 'Permission denied (publickey)' after the invalid format warning
  • The error appears after updating OpenSSH (7.8+) or moving keys between systems
  • Key works on one system but shows invalid format error on another
  • Manual SSH works but ssh-agent or automated tools fail with the warning

Common causes

  1. Key file is in PuTTY/SSH2 format (RFC 4716, with a '---- BEGIN SSH2 PUBLIC KEY ----' header) instead of the single-line OpenSSH format
  2. Public key file is corrupted with extraneous characters, extra whitespace, or line breaks in the middle of the key data
  3. Incorrect line endings: Windows CRLF (\r\n) instead of Unix LF (\n) after the key was edited or transferred
  4. A UTF-8 BOM (Byte Order Mark) was prepended to the key file when copying on Windows or using certain editors
  5. Key copied incompletely, missing the trailing newline or part of the key content
  6. Using the wrong filename or referencing the private key file where a public key is expected (or vice versa)
  7. Private key format mismatch: a tool expects old PEM format ('BEGIN RSA PRIVATE KEY') but the file is the newer OpenSSH format ('BEGIN OPENSSH PRIVATE KEY'), or vice versa

How to fix "key_load_public: invalid format"

1Verify the key file format

Check what format your key file is in. The first line should indicate the format:

bash
head -1 ~/.ssh/id_rsa.pub

Expected first lines:
- OpenSSH public key: ssh-rsa AAAAB3NzaC1yc2E... (or ssh-ed25519 AAAA...)
- OpenSSH private key: -----BEGIN OPENSSH PRIVATE KEY-----
- Old PEM private key: -----BEGIN RSA PRIVATE KEY-----

If you see something else, such as ---- BEGIN SSH2 PUBLIC KEY ---- (PuTTY/RFC 4716 format), the key needs to be converted or regenerated into OpenSSH format.

2Regenerate public key from private key

If you still have a valid private key but the public key file is corrupted or missing, regenerate the public key from it:

bash
ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub

This extracts the public key from your private key in the correct single-line OpenSSH format. The new public key file will start with ssh-rsa (or ssh-ed25519). If the private key is passphrase-protected, you will be prompted for the passphrase.

3Remove a UTF-8 BOM if present

If the key was edited on Windows or copied through certain tools, it may have a UTF-8 BOM (an invisible 3-byte sequence at the start of the file). Detect it:

bash
hexdump -C ~/.ssh/id_rsa.pub | head -1

A leading ef bb bf indicates a BOM. Strip it with sed:

bash
sed -i '1s/^\xef\xbb\xbf//' ~/.ssh/id_rsa.pub

After removing it, re-check the key and test SSH.

4Fix line endings on Windows keys

If you transferred the key from Windows, it may have CRLF (\r\n) line endings instead of LF (\n). Convert them:

bash
# Using dos2unix
dos2unix ~/.ssh/id_rsa ~/.ssh/id_rsa.pub

# Or with sed
sed -i 's/\r$//' ~/.ssh/id_rsa
sed -i 's/\r$//' ~/.ssh/id_rsa.pub

Verify with file:

bash
file ~/.ssh/id_rsa.pub

It should report ASCII text (or OpenSSH ... public key). If it reports ASCII text, with CRLF line terminators, the conversion did not take effect.

5Convert PuTTY (.ppk) keys to OpenSSH format

PuTTY's .ppk files are not in OpenSSH format. Use PuTTYgen (puttygen), the correct tool for converting them. ssh-keygen -i does not read .ppk files — it only imports RFC 4716 / PKCS#8 *public* keys — so do not use it here.

Using puttygen on the command line (Linux/macOS/WSL):

bash
# Export the private key in OpenSSH format
puttygen id_rsa.ppk -O private-openssh -o ~/.ssh/id_rsa

# Export the matching public key
puttygen id_rsa.ppk -O public-openssh -o ~/.ssh/id_rsa.pub

Install puttygen first if needed (sudo apt install putty-tools on Debian/Ubuntu, brew install putty on macOS).

Using the PuTTYgen GUI (Windows):
1. Open PuTTYgen.
2. Click File -> Load private key and select your .ppk file (enter the passphrase if prompted).
3. Click Conversions -> Export OpenSSH key and save it as id_rsa (no .ppk extension).
4. Copy the contents of the "Public key for pasting into authorized_keys file" box into id_rsa.pub.

After converting, set the correct permissions (see the permissions step) before using the key.

6Convert between OpenSSH and PEM private-key formats

If a tool rejects your private key because it expects the older PEM format (-----BEGIN RSA PRIVATE KEY-----) rather than the newer OpenSSH format (-----BEGIN OPENSSH PRIVATE KEY-----), convert it in place. ssh-keygen -p changes the on-disk format with the -m flag. The valid values for -m are RFC4716, PKCS8, and PEM.

Convert an existing private key to old PEM format:

bash
ssh-keygen -p -f ~/.ssh/id_rsa -m PEM

You will be prompted for the current passphrase (if any) and a new one; press Enter to keep it unchanged. Make a backup of the key first (cp ~/.ssh/id_rsa ~/.ssh/id_rsa.bak) so you can recover if the conversion is not what you wanted.

If instead you need to (re)generate a key directly in PEM format:

bash
ssh-keygen -t rsa -b 4096 -m PEM -f ~/.ssh/id_rsa

Note: generating a new key creates a *different* key pair, so you must re-add the new public key to every server's authorized_keys. Avoid -N "" (empty passphrase) for keys that protect real systems; use a passphrase and let ssh-agent cache it.

7Set correct file permissions

SSH refuses to use key files with overly permissive modes. Even when the format is correct, wrong permissions can cause failures:

bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub

Verify:

bash
ls -la ~/.ssh/

The private key should show -rw------- (600) and the public key -rw-r--r-- (644).

8Test the key and check for corruption

After fixing the format, confirm the key parses cleanly:

bash
ssh-keygen -l -f ~/.ssh/id_rsa.pub

This prints the key fingerprint, confirming the file is in a valid format. If it still reports "invalid format", the file is likely truncated or corrupted beyond repair and the key pair should be regenerated:

bash
# Preferred: Ed25519
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -C "your_email@example.com"

# Or RSA (4096-bit)
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -C "your_email@example.com"

Use a passphrase when prompted. Then add the new public key to each server's ~/.ssh/authorized_keys (for example with ssh-copy-id) and test the connection with ssh -v to confirm the key is now offered and accepted.

Advanced notes

OpenSSH version differences: OpenSSH 7.8 (2018) changed the default private key format from PEM to the OpenSSH format for better security. Keys generated on a newer system may not be recognized by very old OpenSSH versions, and vice versa. If a format mismatch is the issue, regenerate the public key from the private key with ssh-keygen -y, or convert the private key with ssh-keygen -p -m PEM (valid -m values are RFC4716, PKCS8, PEM).

Ed25519 vs RSA keys: Modern OpenSSH prefers Ed25519 keys for better security and performance. If you have old RSA keys, consider migrating:
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -C "your_email@example.com"

SSH agent and stale keys: If the error appears only when using ssh-agent, the agent may have cached a bad or stale key. Clear it and reload: ssh-add -D then ssh-add ~/.ssh/id_ed25519.

Check key integrity: ssh-keygen -l -f keyfile prints a key's fingerprint. If that command itself fails, the file is corrupted or in an unsupported format and must be converted or regenerated.

Distro-specific issues: Some legacy distributions (CentOS 6, older RHEL) ship very old OpenSSH versions that do not support modern key formats. On such systems, update OpenSSH where possible; only fall back to an older key type (ssh-keygen -t rsa -b 2048 -m PEM) when an upgrade is genuinely not an option, since older defaults are weaker.

Frequently asked questions

What does "key_load_public: invalid format" mean?
OpenSSH relies on strict key file formats. When the SSH client or server attempts to load a public key using the key_load_public() function, it validates the file structure against expected formats. If the key file contains unexpected bytes, incorrect line endings, a UTF-8 BOM marker, or uses an incompatible format (such as PuTTY's RFC 4716 format with a ---- BEGIN SSH2 PUBLIC KEY ---- header instead of the single-line OpenSSH format), the parser rejects it with "invalid format".
How do I fix "key_load_public: invalid format"?
OpenSSH fails to parse an SSH key file with "key_load_public: invalid format". Usually caused by PuTTY-format keys, BOM/CRLF corruption, or a wrong key format. Convert or regenerate the key in OpenSSH format to fix it.
What causes "key_load_public: invalid format"?
Key file is in PuTTY/SSH2 format (RFC 4716, with a '---- BEGIN SSH2 PUBLIC KEY ----' header) instead of the single-line OpenSSH format Public key file is corrupted with extraneous characters, extra whitespace, or line breaks in the middle of the key data Incorrect line endings: Windows CRLF (\r\n) instead of Unix LF (\n) after the key was edited or transferred
Is the "key_load_public: invalid format" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading