How to fix gpg: unusable public key in Git

GitINTERMEDIATEMEDIUMUpdated Dec 6, 2025ยท 170 views

This GPG error occurs when Git cannot use your GPG key for signing commits or tags. The key may be expired, lack signing capability, or have trust issues. Fixing it involves checking key status and renewing or reconfiguring the key.

Quick fix

Fixes gpg: unusable public key

gpg --list-keys --keyid-format LONG
  1. Check the GPG key status and capabilities
  2. Check secret key availability
  3. Renew an expired GPG key
  4. Set the key trust level
git โ€” error
gpg --list-keys --keyid-format LONG
gpg: unusable public key

What this error means

When you sign Git commits or tags with GPG, Git uses the `gpg` command to create cryptographic signatures. The "unusable public key" error means GPG found your key but cannot use it for the requested operation. GPG keys have capabilities and expiration dates. A key might be flagged for encryption only (E) but not signing (S), or the key/subkey may have expired. GPG also requires keys to have a minimum trust level before using them for certain operations. This error commonly occurs when: - Your GPG key or its signing subkey has expired - The key lacks the signing capability flag [S] - You migrated keys between machines without proper trust settings - The public key is missing required subkeys (common after partial key exports) - GPG version mismatch between when the key was created and current usage

Typical symptoms

  • Git commit signing fails with 'gpg: unusable public key' error
  • Signed tags cannot be created
  • Error message shows key ID followed by 'unusable public key'
  • Previously working commit signing suddenly fails
  • Key works for encryption but not for signing
  • Error appears after migrating to a new machine

Common causes

  1. GPG key or signing subkey has expired (most common)
  2. Key lacks signing capability [S] flag - may only have encryption [E]
  3. Key trust level is undefined or set to 'never'
  4. Public key was exported without necessary subkeys
  5. GPG keyring is corrupted or incomplete after migration
  6. Git configured to use a key ID that doesn't exist in keyring
  7. GPG version incompatibility between key creation and current usage

How to fix "gpg: unusable public key"

1Check the GPG key status and capabilities

First, list your GPG keys to identify the problem:

bash
gpg --list-keys --keyid-format LONG

Look for your key and check for:
- Expiration: Does it show expired next to the key?
- Capabilities: Look for [SC] (Sign, Certify) or [S] (Sign only)

Example output:

bash
pub   rsa4096/30F2B65B9246B6CA 2022-01-15 [SC] [expired: 2024-01-15]
      Key fingerprint = ABCD 1234 5678 EFGH...
uid                 [expired] Your Name <email@example.com>
sub   rsa4096/B7ABC0813E4028C0 2022-01-15 [E] [expired: 2024-01-15]

If you see [expired], proceed to renew the key. If you only see [E] without [S], the key cannot sign.

2Check secret key availability

Verify you have the secret (private) key, not just the public key:

bash
gpg --list-secret-keys --keyid-format LONG

If this returns empty but --list-keys shows your key, you only have the public key. You need to import your private key:

bash
gpg --import your-private-key.asc

After importing, verify it appears in the secret keys list.

3Renew an expired GPG key

If your key expired, you can extend its validity:

bash
gpg --edit-key YOUR_KEY_ID

At the gpg> prompt:

bash
gpg> expire

Enter a new expiration period (e.g., 1y for one year, 0 for never expires).

If you have subkeys, select and renew each one:

bash
gpg> key 1
gpg> expire
gpg> key 2
gpg> expire

Save changes:

bash
gpg> save

After renewing, export and update your public key on GitHub/GitLab:

bash
gpg --armor --export YOUR_KEY_ID
4Set the key trust level

If the key is valid but untrusted, set its trust level:

bash
gpg --edit-key YOUR_KEY_ID

At the gpg> prompt:

bash
gpg> trust

Select option 5 (ultimate trust) for your own key:

bash
Please decide how far you trust this user to correctly verify other users' keys
  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5

Confirm and save:

bash
gpg> quit
5Verify Git is configured with the correct key

Check which key Git is configured to use:

bash
git config --global user.signingkey

This should match a key ID from gpg --list-secret-keys. If empty or wrong, set it:

bash
git config --global user.signingkey YOUR_KEY_ID

Also verify Git is using the correct GPG binary:

bash
git config --global gpg.program

If you have gpg2, you may need:

bash
git config --global gpg.program gpg2

Or on macOS with Homebrew:

bash
git config --global gpg.program /opt/homebrew/bin/gpg
6Test commit signing

After fixing the key, test that signing works:

bash
echo "test" | gpg --clearsign

This should prompt for your passphrase and output signed text. If this works, test Git:

bash
git commit --allow-empty -S -m "Test signed commit"

Verify the signature:

bash
git log --show-signature -1

You should see "Good signature from..." in the output.

Advanced notes

### GPG Key Capability Flags

GPG keys have capability flags that determine what operations they can perform:
- [C] - Certify: Can sign other keys (master key only)
- [S] - Sign: Can create signatures (needed for Git commits)
- [E] - Encrypt: Can encrypt data
- [A] - Authenticate: Can authenticate (SSH, etc.)

If your key only shows [E], it's an encryption-only key and cannot sign. You'll need to either:
1. Create a new key with signing capability: gpg --full-generate-key
2. Add a signing subkey to your existing key: gpg --edit-key KEY_ID then addkey

### Migrating Keys Between Machines

When copying GPG keys to a new machine, export BOTH the public and secret keys:

bash
# On source machine
gpg --export-secret-keys --armor YOUR_KEY_ID > private.asc
gpg --export --armor YOUR_KEY_ID > public.asc
gpg --export-ownertrust > trust.txt

# On target machine
gpg --import private.asc
gpg --import public.asc
gpg --import-ownertrust trust.txt

Without the trust database, your key may show as untrusted even with all key material present.

### GPG Agent Issues

Sometimes the GPG agent caches incorrect state. Restart it:

bash
gpgconf --kill gpg-agent
gpg-agent --daemon

Or reload:

bash
gpg-connect-agent reloadagent /bye

### Using Different GPG Versions

If you created keys with GPG 2.x but Git is using GPG 1.x (or vice versa), they may use different keyrings. Check versions:

bash
gpg --version
gpg2 --version

List keys with both to see if they differ:

bash
gpg --list-secret-keys --keyid-format LONG
gpg2 --list-secret-keys --keyid-format LONG

Configure Git to use the correct one:

bash
git config --global gpg.program gpg2

### Debugging with Verbose Output

For detailed troubleshooting, run GPG with debug flags:

bash
gpg -v --debug-level guru --sign test.txt

Or check Git's GPG interaction:

bash
GIT_TRACE=1 git commit -S -m "test"

### Creating a New Signing Subkey

If your key lacks signing capability, add a subkey:

bash
gpg --edit-key YOUR_KEY_ID
gpg> addkey

Select RSA (sign only) and set desired key size and expiration. Then:

bash
gpg> save

Update your public key on GitHub/GitLab after adding the subkey.

Frequently asked questions

What does "gpg: unusable public key" mean?
When you sign Git commits or tags with GPG, Git uses the gpg command to create cryptographic signatures. The "unusable public key" error means GPG found your key but cannot use it for the requested operation. GPG keys have capabilities and expiration dates.
How do I fix "gpg: unusable public key"?
This GPG error occurs when Git cannot use your GPG key for signing commits or tags. The key may be expired, lack signing capability, or have trust issues. Fixing it involves checking key status and renewing or reconfiguring the key.
What causes "gpg: unusable public key"?
GPG key or signing subkey has expired (most common) Key lacks signing capability [S] flag - may only have encryption [E] Key trust level is undefined or set to 'never'
Is the "gpg: unusable public key" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading