How to Fix Git Commit Signing Failed: "gpg: Signing Failed: Secret Key Not Available"
Quick answer
You've enabled commit signing in Git, and now every commit attempt fails because GPG can't find the secret key it needs to actually sign anything. This means...
You've enabled commit signing in Git, and now every commit attempt fails because GPG can't find the secret key it needs to actually sign anything. This means Git is correctly trying to sign the commit as configured, but the specific key ID it's been told to use either doesn't exist in your GPG keyring, or exists but without its private component available.
The Problem
A normal commit fails instead of completing:
$ git commit -m "Add feature"
error: gpg failed to sign the data
fatal: failed to write commit object
Running GPG directly against the configured key reveals the more specific underlying error:
$ echo "test" | gpg --clearsign
gpg: skipped "A1B2C3D4E5F6A7B8": No secret key
gpg: signing failed: Secret key not available
Why It Happens
Git's commit signing relies on GPG having both the public and private components of the key configured in user.signingkey actually present and accessible in your local keyring. This error means GPG located a reference to the key ID (or found nothing matching it at all) but doesn't have the private key material needed to actually produce a signature. Common causes:
- The configured signing key ID doesn't match any key you actually have β a typo, a copy-paste error, or referencing a key ID from a different machine or a previous GPG setup that was never actually imported here.
- Only the public key is present, not the private key β you imported someone's public key (or your own public key without its private counterpart) for verification purposes, but never actually generated or imported the matching private key needed for signing.
- The private key exists but in a different GPG keyring or on a different machine β common after setting up a new development machine without migrating your existing GPG keys over.
- The key has expired, and GPG is correctly refusing to use an expired key for new signatures.
- A GPG agent or pinentry configuration issue preventing GPG from actually accessing an otherwise valid private key that requires a passphrase prompt.
The Fix
First, check what signing key Git is actually configured to use:
git config --get user.signingkey
A1B2C3D4E5F6A7B8
List the secret keys GPG actually has available, and compare against that configured ID:
gpg --list-secret-keys --keyid-format=long
sec rsa4096/9F8E7D6C5B4A3210 2025-01-15 [SC]
1234567890ABCDEF1234567890ABCDEF12345678
uid [ultimate] Your Name <you@example.com>
If the key ID Git is configured to use doesn't match any key in this list, update Git's configuration to point at the correct one, using the key ID actually shown in your secret keyring:
git config --global user.signingkey 9F8E7D6C5B4A3210
If no secret key exists at all, generate a new one:
gpg --full-generate-key
Follow the prompts to create a key, then configure Git to use it:
gpg --list-secret-keys --keyid-format=long
git config --global user.signingkey <your-new-key-id>
git config --global commit.gpgsign true
Don't forget to also add the corresponding public key to your GitHub/GitLab account so signed commits show as verified there, not just locally:
gpg --armor --export <your-key-id>
Copy the output and add it under your Git hosting platform's GPG key settings.
If you're setting up a new machine and the key genuinely exists elsewhere, export it from your original machine and import it on the new one, rather than generating a completely new key (which would mean previously-signed commits no longer match your currently active key):
# On the original machine
gpg --export-secret-keys --armor <key-id> > private-key.asc
# On the new machine (transfer this file securely!)
gpg --import private-key.asc
If the key has expired, extend its expiration rather than generating a new one, preserving continuity with previously signed commits:
gpg --edit-key <key-id>
gpg> expire
gpg> save
Still Not Working?
If the correct key is present but signing still fails, particularly on macOS or in certain terminal/IDE combinations, check whether GPG's pinentry program (responsible for prompting for your key's passphrase) is correctly configured for your environment β a broken pinentry setup can cause signing to silently fail rather than actually prompting you for the passphrase it needs:
echo "test" | gpg --clearsign
If this hangs or fails without ever showing a passphrase prompt, reinstall or reconfigure pinentry for your platform (commonly pinentry-mac on macOS, or the appropriate GTK/Qt variant on Linux) and ensure gpg-agent.conf correctly references it:
echo "pinentry-program /usr/local/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent