Fix 'gpg failed to sign the data' Error When Committing in VS Code

intermediate๐Ÿ’ป VS Code2026-07-17| VS Code (all versions), Git 2.x, macOS / Linux / Windows (WSL2), GPG 2.x

Error Message

error: gpg failed to sign the data fatal: failed to write commit object
#git#gpg#commit-signing#source-control

The Error

You stage your changes in VS Code, hit commit โ€” and instead of a clean commit, you get:

error: gpg failed to sign the data
fatal: failed to write commit object

The Source Control panel shows a generic failure. No passphrase prompt, no hint about what went wrong. What makes it maddening: the same commit might work fine from a regular terminal. VS Code's integrated terminal and GUI commit flow are often the culprit โ€” they don't always inherit the full shell environment.

Why This Happens

With commit.gpgsign = true in your Git config, every commit must be signed. There are a handful of ways this can break:

  • The GPG agent is not running or has crashed
  • GPG_TTY is not set, so GPG can't prompt for a passphrase
  • The pinentry program can't display a dialog (common in VS Code's terminal context)
  • The configured signing key doesn't exist or has expired
  • On macOS: GPG Suite's pinentry-mac isn't wired up correctly

VS Code makes this harder to debug. Its integrated terminal and GUI commit flow don't always inherit your full shell environment โ€” which means GPG_TTY goes unset and the agent socket may be missing, silently.

Fix 1: Restart the GPG Agent

Start here. Kill the agent and let it respawn on the next GPG call:

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

Try your commit again. If the agent had crashed or gotten into a bad state, this one step is often all it takes.

Fix 2: Set GPG_TTY in Your Shell Profile

GPG needs a TTY to show the passphrase prompt. In VS Code's integrated terminal, GPG_TTY is often not set โ€” which means the signing attempt fails silently.

Add this line to your ~/.bashrc, ~/.zshrc, or ~/.bash_profile:

export GPG_TTY=$(tty)

Reload your shell:

source ~/.zshrc   # or ~/.bashrc

Open a fresh VS Code terminal and try committing again. On Linux, this is the most common fix.

Fix 3: Switch to pinentry-tty (Linux)

Still no passphrase dialog? Switch to the terminal-based pinentry. First, find where it lives on your system:

which pinentry-tty
# common paths: /usr/bin/pinentry-tty or /usr/local/bin/pinentry-tty

Then configure it and restart the agent:

echo "pinentry-program /usr/bin/pinentry-tty" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent

Test GPG directly before touching Git:

echo "test" | gpg --clearsign

If that prompts for your passphrase and signs cleanly, VS Code commits will work too.

Fix 4: macOS โ€” Use pinentry-mac

macOS is particular here. Without pinentry-mac, GPG has no way to show a dialog when called from VS Code's Source Control panel โ€” there's simply no terminal to prompt you in. Install it first:

brew install pinentry-mac

Then wire it up:

echo "pinentry-program $(which pinentry-mac)" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent

After this, you'll get a native macOS passphrase dialog even when committing through the GUI โ€” no terminal required.

Fix 5: Check Your Signing Key

Worth ruling out: maybe Git is configured with a key that doesn't exist or has expired. Start by checking what Git thinks it should use:

git config --global user.signingkey

Then list what GPG actually has:

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

You'll see output like:

sec   rsa4096/3AA5C34371567BD2 2021-03-01 [SC]
      ...
uid   Your Name <you@example.com>

The value after the / on the sec line is your key ID. If it doesn't match your Git config, update it:

git config --global user.signingkey 3AA5C34371567BD2

Also check the expiry dates in the output. An expired key needs to be renewed or replaced before signing will work again.

Fix 6: Commit from the Terminal (Workaround)

When the GUI commit flow keeps failing, bypass it. Open the integrated terminal and commit directly:

git commit -m "your message"

With GPG_TTY set in your shell profile and the agent running, this usually works. It sidesteps whatever environment problem VS Code's Source Control panel has.

Fix 7: Temporarily Disable GPG Signing

Need to ship something right now? Skip signing for this one commit:

git commit --no-gpg-sign -m "your message"

Or turn it off globally while you debug the root cause:

git config --global commit.gpgsign false

Re-enable it once the GPG setup is sorted:

git config --global commit.gpgsign true

Verifying the Fix

Before calling it done, run a quick end-to-end check:

# Confirm GPG can sign and the passphrase prompt works
echo "test" | gpg --clearsign

# Make an empty commit and inspect the signature
git commit --allow-empty -m "test gpg signing"
git log --show-signature -1

In the git log output, look for:

gpg: Signature made Wed Jul 16 10:00:00 2026 JST
gpg:                using RSA key 3AA5C34371567BD2
gpg: Good signature from "Your Name <you@example.com>"

That "Good signature" line is what you're after. Everything is wired up correctly.

Prevention

A few habits that stop this from coming back:

  • Add export GPG_TTY=$(tty) to your shell profile permanently โ€” not just the current session
  • On macOS, use pinentry-mac so passphrase dialogs work everywhere, including GUI tools
  • Keep an eye on key expiry: gpg --list-keys shows the dates; set a calendar reminder when you renew
  • On multiple machines, import the GPG key on each one โ€” copying just the Git config isn't enough
  • Consider SSH signing if you want less friction: git config --global gpg.format ssh

Related Error Notes