The 'Load key invalid format' error occurs when OpenSSH cannot parse your private key file because it's in an incompatible format. This commonly happens when the key is in the newer OpenSSH format (introduced in OpenSSH 7.8) but your SSH client or tool expects the traditional PEM format.
The "Load key invalid format" error indicates that SSH is trying to read your private key file but cannot recognize its format. OpenSSH supports two main formats for RSA and other key types: 1. **Old PEM format** (starting with `-----BEGIN RSA PRIVATE KEY-----`) - Traditional OpenSSL-compatible format - Supported by most SSH clients and tools - Default before OpenSSH 7.8 2. **New OpenSSH format** (starting with `-----BEGIN OPENSSH PRIVATE KEY-----`) - Introduced in OpenSSH 7.8 (2018) - Default for newly generated keys on modern systems - Better protection against offline password guessing - Some older tools don't support this format When SSH encounters an OpenSSH format key but expects PEM format (or vice versa), it cannot parse the key and throws this error. The issue is particularly common with: - Tools built before OpenSSH 7.8 became standard - Cross-platform usage (Windows with older PuTTY versions) - Cloud platforms and CI/CD systems with legacy SSH clients - Converted keys that were improperly formatted during conversion
First, determine which format your key is in by examining the first line:
head -1 ~/.ssh/id_rsaIf you see:
- -----BEGIN OPENSSH PRIVATE KEY----- → Your key is in OpenSSH format
- -----BEGIN RSA PRIVATE KEY----- → Your key is in PEM format (traditional)
- -----BEGIN EC PRIVATE KEY----- → Your key is an EC key in PEM format
If you see anything else, the key file is corrupted or in an unexpected format.
If your key is in the newer OpenSSH format and you need PEM format, convert it:
# Convert to PEM format
ssh-keygen -p -m PEM -f ~/.ssh/id_rsa
# Press Enter when asked for passphrase (or enter current passphrase)
# Press Enter again to confirm no new passphrase (or enter new passphrase)The key is now in PEM format. Verify the conversion:
head -1 ~/.ssh/id_rsa
# Should now show: -----BEGIN RSA PRIVATE KEY-----Note: If your key is Ed25519, the format header will be different:
# Old Ed25519 headers (still valid):
# -----BEGIN OPENSSH PRIVATE KEY-----
# -----BEGIN EC PRIVATE KEY-----
# Convert to PEM format with -m PEM flagIf the key file is corrupted or you want a fresh start, generate a new key in PEM format:
# Generate new RSA key in PEM format
ssh-keygen -t rsa -m PEM -f ~/.ssh/id_rsa_pem
# Don't overwrite your existing key unless you're sure
# You'll be prompted to enter a passphraseFor other key types in PEM format:
# Ed25519 key in PEM format
ssh-keygen -t ed25519 -m PEM -f ~/.ssh/id_ed25519_pem
# ECDSA key in PEM format
ssh-keygen -t ecdsa -m PEM -f ~/.ssh/id_ecdsa_pemAfter generating, add the new public key to your server's ~/.ssh/authorized_keys.
If you're using PuTTY on Windows, use PuTTYgen to convert the key:
Steps:
1. Open PuTTYgen
2. Click "Load" and select your private key file
3. If it's in OpenSSH format, PuTTYgen will show a warning but still load it
4. Go to "Conversions" menu → "Export OpenSSH key" (or "Export PuTTY key")
5. Save the key with a new filename
Alternative: Convert using WSL or Git Bash on Windows:
If you have Git Bash installed (it includes ssh-keygen):
# In Git Bash or WSL
ssh-keygen -p -m PEM -f /path/to/your/keyThis is often easier and more reliable than using PuTTYgen.
After fixing the format, ensure SSH can find and use your key:
# Check key file permissions (must be 600)
ls -l ~/.ssh/id_rsa
# Should show: -rw------- 1 user user
# Fix permissions if needed
chmod 600 ~/.ssh/id_rsa
# Test SSH connection with verbose output
ssh -v user@hostname
# Look for: "Identity added" or "Offering RSA/ED25519 public key"
# Explicitly specify key if SSH can't find it
ssh -i ~/.ssh/id_rsa_pem user@hostnameSSH config file (~/.ssh/config):
If you have multiple keys, specify which to use:
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_pem
IdentitiesOnly yesThe IdentitiesOnly yes prevents SSH from trying default keys that don't work.
Once you've converted or generated a key, verify it works:
# Test with SSH command (verbose mode shows what's happening)
ssh -vvv [email protected]
# Look for these success indicators:
# "Identity added:" - SSH loaded your key
# "Offering rsa public key" - SSH is using the key
# "Authentications that can continue: publickey" - Auth succeeded
# For Git over SSH (GitHub, GitLab, Bitbucket)
ssh -T [email protected]
# Should show: Hi username! You've successfully authenticated...
# For SCP or SFTP
scp -i ~/.ssh/id_rsa_pem local_file user@server:/remote/pathIf you still see "invalid format" error:
1. Double-check the key file isn't corrupted (try cat ~/.ssh/id_rsa | head -1)
2. Ensure you're specifying the correct key path
3. Verify the file isn't a symlink to a non-existent file
If you're using SSH keys with cloud platforms or CI/CD (GitHub Actions, GitLab CI, AWS CodeBuild), they may require specific key formats:
GitHub / GitLab:
# Modern versions support OpenSSH format, but PEM is safer
# If you get "invalid format" error, convert to PEM
ssh-keygen -p -m PEM -f ~/.ssh/github_keyAWS / Azure / GCP:
# Cloud platforms often support only PEM format
# Always generate or convert keys to PEM for cloud imports
ssh-keygen -t rsa -m PEM -f ~/my_cloud_keyEnvironment Variable SSH Keys:
If your CI/CD system stores keys as environment variables, ensure they're properly formatted:
# Copy the entire key (including BEGIN/END lines)
cat ~/.ssh/id_rsa | base64 # If storing as base64
# Then paste into environment variableDocker and Kubernetes:
# In a Dockerfile, use PEM format for maximum compatibility
COPY --chown=app:app id_rsa_pem /home/app/.ssh/id_rsa
RUN chmod 600 /home/app/.ssh/id_rsaUnderstanding SSH Key Formats in Detail
OpenSSH 7.8 (released August 2018) changed the default format for newly generated keys. This was a significant change that affects interoperability.
Why OpenSSH Format is Better:
- Enhanced resistance to offline password guessing using bcrypt key derivation
- Support for key comments within private keys
- Allows multiple public/private key pairs in one file (future use)
- More flexible key structure
Why Some Tools Still Need PEM:
- Predates the OpenSSH format change (written before 2018)
- Use OpenSSL libraries that don't understand OpenSSH format
- Designed for maximum portability across Unix/Linux systems
- Some legacy systems mandate PEM format
Converting Keys Safely:
The -p flag to ssh-keygen is designed to change passphrases, but it can also convert formats with the -m flag. This is safe because it decrypts the private key in memory, then re-encrypts in the new format. Your private key is never written unencrypted to disk during conversion.
Key Format Identification:
| Header | Type | Generated By | Format Version |
|--------|------|-------------|-----------------|
| -----BEGIN RSA PRIVATE KEY----- | RSA | OpenSSH < 7.8, ssh-keygen with -m PEM | PKCS#1 (OpenSSL) |
| -----BEGIN EC PRIVATE KEY----- | ECDSA | OpenSSH < 7.8, ssh-keygen with -m PEM | SEC1 (OpenSSL) |
| -----BEGIN OPENSSH PRIVATE KEY----- | Any type | OpenSSH >= 7.8, default ssh-keygen | OpenSSH Proprietary |
| -----BEGIN PRIVATE KEY----- | Any type | OpenSSL, PKCS#8 format | PKCS#8 |
Performance and Security Trade-offs:
- PEM format: Faster decryption (less CPU), less protection against offline attacks
- OpenSSH format: Slower decryption (bcrypt), better protection against password guessing if key has passphrase
- For unencrypted keys, both formats have equivalent security
Checking Your OpenSSH Version:
ssh -V # Shows version
# If you see "OpenSSH 7.8" or later, it defaults to OpenSSH formatCommon Compatibility Issues by Tool:
- Git (all versions): Supports both formats in recent versions
- PuTTY (< 0.76): OpenSSH format not fully supported, use PuTTYgen for conversion
- PuTTY (>= 0.76): Native OpenSSH support
- Terraform: Recommends PEM format for maximum compatibility
- Ansible: Supports OpenSSH format since version 2.2
- AWS CodeCommit: Supports OpenSSH format
- Heroku CLI: May require PEM format for older versions
- Docker/Kubernetes: Works with both, but PEM more portable
Passphrase vs No Passphrase:
Converting format with -p will either:
1. Keep existing passphrase if you press Enter twice
2. Add/change/remove passphrase if you enter new values
For automated systems, consider:
# For CI/CD: unencrypted key in PEM format (environment variable)
ssh-keygen -t rsa -m PEM -N "" -f /tmp/ci_key
# For servers: encrypted key with strong passphrase
ssh-keygen -t rsa -m PEM -C "user@host" -f ~/.ssh/id_rsa
# Then enter a strong passphrase when promptedRecovering from Lost Keys:
Never store passphrase in version control or logs. If lost:
1. Generate new key pair
2. Update public key on servers: ssh-copy-id -i ~/.ssh/new_key user@host
3. Delete old key from ~/.ssh/authorized_keys on servers
Bad owner or permissions on /home/user/.ssh/config
How to fix "Bad owner or permissions on .ssh/config" in SSH
Error connecting to agent: Connection refused
How to fix "Error connecting to agent: Connection refused" in SSH
Connection closed by UNKNOWN port 65535
How to fix 'Connection closed by UNKNOWN port 65535' in SSH
Offending ECDSA key in /home/user/.ssh/known_hosts:line
How to fix "Offending ECDSA key in known_hosts" in SSH
bind: Address already in use
How to fix "bind: Address already in use" in SSH