Skip to content
ecdsa.com
Git (commit -S, tag -s, commit.gpgsign) with GnuPGGit

Error message

error: gpg failed to sign the data

Also printed as

  • fatal: failed to write commit object
  • gpg: skipped "ABCDEF0123456789": No secret key
  • gpg: signing failed: No secret key

Git prints gpg's stderr after the first line, for example 'gpg: skipped "<key>": No secret key' or 'gpg: signing failed: Inappropriate ioctl for device'. When `gpg.program` cannot be started, Git prints "(no gpg output)".

What it means

Git asked GnuPG to sign the commit or tag object and gpg exited with an error, so Git aborted ("fatal: failed to write commit object"). Git's own line says nothing about the cause; the gpg lines printed with it (or `[GNUPG:]` status lines) do. The most common one is "No secret key": the configured `user.signingkey` does not exist in this keyring.

Why it happens

How to fix it

  1. 1.

    Run gpg yourself with the configured key

    If `gpg --clearsign` with the same key fails, the problem is GnuPG, not Git — and its message is the real one.

    bash
    git config --get user.signingkey
    gpg --list-secret-keys --keyid-format=long          # is that key listed, with a "sec" line?
    echo test | gpg --clearsign --local-user "$(git config --get user.signingkey)" > /dev/null && echo "gpg can sign"
  2. 2.

    Point Git at an existing key and make pinentry work

    Use the long key ID or fingerprint of a secret key that exists locally, set `gpg.program` explicitly, and export `GPG_TTY` in your shell.

    bash
    KEY=$(gpg --list-secret-keys --with-colons alice@example.com | awk -F: '/^sec/ {print $5; exit}')
    git config --global user.signingkey "$KEY"
    git config --global gpg.program "$(command -v gpg)"
    export GPG_TTY=$(tty)        # in ~/.bashrc / ~/.zshrc, so pinentry can ask for the passphrase

Related errors

Browse the full signature error database