How to fix error: gpg failed to sign the data: gpg: signing failed: Unusable secret key (key expired) in Git

GitINTERMEDIATEMEDIUMUpdated Dec 6, 2025· 172 views

The 'gpg failed to sign the data' error with 'Unusable secret key (key expired)' occurs when your GPG signing key has passed its expiration date. Git cannot use an expired key to sign commits or tags, but you can renew the key's expiration without creating a new one.

Quick fix

Fixes error: gpg failed to sign the data: gpg: signing failed: Unusable secret key (key expired)

# List your secret keys with expiration dates
gpg --list-secret-keys --keyid-format=long

# Look for output like:
# sec   rsa4096/ABC123DEF456 2020-01-15 [SC] [expired: 2024-01-15]
#       Fingerprint: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
# uid           [ expired] Your Name <email@example.com>
  1. Verify the key is expired
  2. Find your key ID
  3. Extend the key expiration date
  4. Update subkey expiration dates
git — error
# List your secret keys with expiration dates
gpg --list-secret-keys --keyid-format=long
# Look for output like:
# sec rsa4096/ABC123DEF456 2020-01-15 [SC] [expired: 2024-01-15]
# Fingerprint: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
# uid [ expired] Your Name <email@example.com>
error: gpg failed to sign the data: gpg: signing failed: Unusable secret key (key expired)

What this error means

The "gpg failed to sign the data" error with "Unusable secret key (key expired)" indicates that your GPG key's expiration date has passed. GPG keys can be configured with an expiration date as a security measure—a "dead-man switch" that prevents indefinite use of a key if it's compromised or abandoned. When you attempt to sign a Git commit or tag, Git invokes GPG to create a cryptographic signature. If the key specified in your `user.signingkey` configuration has expired, GPG refuses to use it, causing the commit to fail. This is a protective measure: expired keys shouldn't be trusted for new signatures. The good news is that GPG key expiration dates can be extended even after expiration. The private key itself never expires—only the public key's metadata contains the expiration date. You can renew your key, update the expiration date, and continue using the same key identity without losing your commit verification history.

Typical symptoms

  • Git commits fail with 'error: gpg failed to sign the data' and 'Unusable secret key'
  • Error message specifically mentions 'key expired' in the GPG output
  • Running 'echo test | gpg -bsau <keyid>' shows 'Unusable secret key'
  • Previously working commit signing suddenly stops working
  • gpg --list-keys shows an expired date next to your signing key
  • Git tag signing fails with the same GPG error
  • Commits that were signed before expiration still verify correctly
  • The error appears even though the key exists in your keyring

Common causes

  1. GPG key expiration date has passed (most common—keys often expire after 1-2 years)
  2. Signing subkey expired while primary key is still valid
  3. Local repository configured with an old key while global config uses a different key
  4. Key was created with a short expiration period and needs renewal
  5. Multiple GPG keys exist and Git is using the expired one
  6. Key was imported from backup without updating after previous renewal

How to fix "error: gpg failed to sign the data: gpg: signing failed: Unusable secret key (key expired)"

1Verify the key is expired

First, confirm that key expiration is the actual issue:

bash
# List your secret keys with expiration dates
gpg --list-secret-keys --keyid-format=long

# Look for output like:
# sec   rsa4096/ABC123DEF456 2020-01-15 [SC] [expired: 2024-01-15]
#       Fingerprint: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
# uid           [ expired] Your Name <email@example.com>

If you see [expired: DATE] next to your key, the expiration date has passed.

You can also test signing directly:

bash
# Replace ABC123DEF456 with your key ID
echo "test" | gpg --clearsign -u ABC123DEF456

# If expired, you'll see:
# gpg: signing failed: Unusable secret key
2Find your key ID

Identify the key ID you need to renew:

bash
# List keys with long format IDs
gpg --list-secret-keys --keyid-format=long

# Output example:
# sec   rsa4096/ABC123DEF456789AB 2020-01-15 [SC] [expired: 2024-01-15]
#       XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# uid           [ expired] John Doe <john@example.com>
# ssb   rsa4096/DEF789GHI123456CD 2020-01-15 [E] [expired: 2024-01-15]

The key ID is the part after the slash on the sec line (e.g., ABC123DEF456789AB).

You can also check which key Git is configured to use:

bash
# Check global config
git config --global user.signingkey

# Check local repo config (may override global)
git config --local user.signingkey
3Extend the key expiration date

Renew your key by editing it in GPG's interactive mode:

bash
# Start editing the key (use your key ID)
gpg --edit-key ABC123DEF456789AB

In the GPG interactive prompt:

bash
gpg> expire
Changing expiration time for the primary key.
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y

Enter your desired validity period (e.g., 1y for one year, 2y for two years, or 0 for no expiration).

You'll be prompted to confirm and enter your passphrase:

bash
Is this correct? (y/N) y

You need a passphrase to unlock the secret key for
user: "John Doe <john@example.com>"
4Update subkey expiration dates

If you have signing or encryption subkeys, update them too:

bash
gpg> list
# Shows all keys and subkeys with numbers

gpg> key 1
# Selects the first subkey (an asterisk appears next to it)

gpg> expire
Key is valid for? (0) 1y
Is this correct? (y/N) y

# If you have more subkeys, repeat:
gpg> key 1
# Deselects key 1
gpg> key 2
# Selects key 2
gpg> expire
...

After updating all keys:

bash
gpg> save

This saves the changes and exits the GPG prompt.

5Verify the renewal worked

Confirm the key now has a valid expiration date:

bash
# List keys again
gpg --list-secret-keys --keyid-format=long

# Should now show future date:
# sec   rsa4096/ABC123DEF456789AB 2020-01-15 [SC] [expires: 2025-12-01]

Test signing:

bash
echo "test" | gpg --clearsign -u ABC123DEF456789AB

# Should produce a signed message without errors

Test a Git commit:

bash
git commit --allow-empty -S -m "Test signed commit"
# Should succeed without GPG errors
6Update the key on GitHub/GitLab

After renewing, you must update your public key on hosting platforms:

bash
# Export your renewed public key
gpg --armor --export ABC123DEF456789AB

For GitHub:
1. Go to Settings → SSH and GPG keys
2. Delete the old GPG key entry
3. Click "New GPG key"
4. Paste the exported public key
5. Save

For GitLab:
1. Go to User Settings → GPG Keys
2. Remove the old key
3. Add the new public key

Note: Previously signed commits will remain verified because the signature was valid at the time of signing. The renewed key maintains the same identity.

7Publish to keyservers (optional)

If you use public keyservers, update them with your renewed key:

bash
# Send to Ubuntu keyserver
gpg --keyserver keyserver.ubuntu.com --send-keys ABC123DEF456789AB

# Send to MIT keyserver
gpg --keyserver pgp.mit.edu --send-keys ABC123DEF456789AB

# Send to keys.openpgp.org (requires email verification)
gpg --keyserver keys.openpgp.org --send-keys ABC123DEF456789AB

This allows others who verify your signatures to get the updated expiration date.

8Quick renewal method (GPG 2.1.22+)

For GPG version 2.1.22 or later, you can use a non-interactive command:

bash
# Get your key fingerprint
gpg --list-secret-keys --keyid-format=long

# Extend primary key expiration by 1 year
gpg --quick-set-expire FINGERPRINT 1y

# Example with full fingerprint:
gpg --quick-set-expire XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 1y

To also update subkeys:

bash
# List subkey fingerprints
gpg --list-keys --with-subkey-fingerprint ABC123DEF456789AB

# Update each subkey
gpg --quick-set-expire SUBKEY_FINGERPRINT 1y

You can specify exact dates using ISO format (2025-12-31) or relative periods (6m, 2y).

9Fix repository using wrong key

If your repository has a local key configuration pointing to an expired key:

bash
# Check if local config overrides global
git config --local user.signingkey

# If it shows an old/expired key, remove it
git config --local --unset user.signingkey

# Or update it to your current key
git config --local user.signingkey ABC123DEF456789AB

Verify Git is now using the correct key:

bash
git config user.signingkey

Advanced notes

### Understanding GPG Key Expiration

GPG key expiration is a security feature, not a limitation:
- Private keys never expire — only the public key metadata contains the expiration date
- Expired keys can still be renewed — you always have full control over keys you own
- Signatures made before expiration remain valid — the expiration affects future use only
- Expiration acts as a dead-man switch — if you lose access, the key automatically becomes untrusted

### Setting Appropriate Expiration Periods

Best practices for expiration dates:
- 1-2 years is a good balance between security and convenience
- Never set no expiration for keys used in production environments
- Shorter periods (3-6 months) for high-security environments
- Set calendar reminders to renew before expiration

### Backing Up Your Key

After renewal, back up your key:

bash
# Export secret key (keep this secure!)
gpg --export-secret-keys --armor ABC123DEF456789AB > private-key-backup.asc

# Export public key
gpg --export --armor ABC123DEF456789AB > public-key-backup.asc

# Export trust database
gpg --export-ownertrust > trustdb-backup.txt

Store backups in a secure location (encrypted drive, password manager, etc.).

### Multiple Keys Scenario

If you have multiple GPG keys:

bash
# List all secret keys
gpg --list-secret-keys

# Set the correct one as default for Git
git config --global user.signingkey CORRECT_KEY_ID

# Optionally, delete old/unused keys
gpg --delete-secret-keys OLD_KEY_ID
gpg --delete-keys OLD_KEY_ID

### Disabling Commit Signing Temporarily

If you need to commit urgently while fixing the key:

bash
# Single commit without signing
git commit --no-gpg-sign -m "Your message"

# Or disable globally temporarily
git config --global commit.gpgsign false

# Don't forget to re-enable later
git config --global commit.gpgsign true

### Signing With a Specific Key

If you have multiple keys, specify which to use:

bash
# Per-repository
git config user.signingkey SPECIFIC_KEY_ID

# Or per-commit
git commit -S<keyid> -m "Message"

### WSL and Windows Considerations

On Windows Subsystem for Linux (WSL):
- Ensure GPG agent is running: gpg-agent --daemon
- You may need to set GPG_TTY: export GPG_TTY=$(tty)
- Consider using Windows GPG with Git for Windows instead

### Troubleshooting GPG Agent

If issues persist after renewal:

bash
# Restart GPG agent
gpgconf --kill gpg-agent
gpg-agent --daemon

# Clear cached passphrases
echo RELOADAGENT | gpg-connect-agent

Frequently asked questions

What does "error: gpg failed to sign the data: gpg: signing failed: Unusable secr" mean?
The "gpg failed to sign the data" error with "Unusable secret key (key expired)" indicates that your GPG key's expiration date has passed. GPG keys can be configured with an expiration date as a security measure—a "dead-man switch" that prevents indefinite use of a key if it's compromised or abandoned. When you attempt to sign a Git commit or tag, Git invokes GPG to create a cryptographic signature.
How do I fix "error: gpg failed to sign the data: gpg: signing failed: Unusable secr"?
The 'gpg failed to sign the data' error with 'Unusable secret key (key expired)' occurs when your GPG signing key has passed its expiration date. Git cannot use an expired key to sign commits or tags, but you can renew the key's expiration without creating a new one.
What causes "error: gpg failed to sign the data: gpg: signing failed: Unusable secr"?
GPG key expiration date has passed (most common—keys often expire after 1-2 years) Signing subkey expired while primary key is still valid Local repository configured with an old key while global config uses a different key
Is the "error: gpg failed to sign the data: gpg: signing failed: Unusable secr" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading