Git

How to Fix Git Commit Signing Failed: "gpg: Signing Failed: Secret Key Not Available"

4 min read by DebuggedIt

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