Skip to content

Instantly share code, notes, and snippets.

@paolocarrasco
Last active November 5, 2024 20:08
Show Gist options
  • Save paolocarrasco/18ca8fe6e63490ae1be23e84a7039374 to your computer and use it in GitHub Desktop.
Save paolocarrasco/18ca8fe6e63490ae1be23e84a7039374 to your computer and use it in GitHub Desktop.
How to understand the `gpg failed to sign the data` problem in git

Problem

You have installed GPG, then tried to commit and suddenly you see this error message after it:

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

Debug

For understanding what's going on, first check what git is doing, so add GIT_TRACE=1 at the beginning of the command you used before (git commit or git rebase):

GIT_TRACE=1 git commit

With that you can see what GPG is doing: Probably you will see something like this

10:37:22.346480 run-command.c:637       trace: run_command: gpg --status-fd=2 -bsau <your GPG key>

(Check if your GPG key is correct)

Execute that gpg command again in the command line:

gpg --status-fd=2 -bsau <your GPG key>

👆🏻 With this now you could see what happened in detail!

Solutions

We can have many problems, but I list what I found:

  1. It could be that the GPG key was expired: https://stackoverflow.com/a/47561300/532912

  2. Another thing could be that the secret key was not set properly (In my case the message said gpg: signing failed: No secret key as it can be see in the image below). image It means that is not finding the key that was set. You would need to set up the GPG key in Git (again):

    • List the secret keys available in GPG.
    gpg --list-secret-keys --keyid-format=long
    • Copy your key
    • Set your key for your user in git
    git config --global user.signingkey <your key>
  3. Another popular solution that could help was shared here by @NirajanMahara: https://gist.github.com/paolocarrasco/18ca8fe6e63490ae1be23e84a7039374?permalink_comment_id=3767413#gistcomment-3767413

  4. You can see in the thread of this gist other ways to find the solution to other problems. I recommend to read the Github guide for signing commits with GPG.

Hope it helps!

@lnasc256
Copy link

thank you

@marionorthvolt
Copy link

I was trying to solve this for 2 days! thanks!

@Lippiece
Copy link

Lippiece commented Dec 2, 2022

  1. then use export GPG_TTY=$(tty)

It also helped to to set it permanently in ~/.profile on Ubuntu (to do so, append export GPG_TTY=$(tty) to the ~/.profile file).

@gcakir
Copy link

gcakir commented Dec 12, 2022

I had the same issue. The output of the command gpg --status-fd=2 -bsau was fine. It turns out my git config in the repo was the problematic. I deleted the [user] and [gpg] entries in .git/config, and then I reconfigured the pgp globally via git config --global gpg.program gpg and git config --global user.signingkey "<my signing key>" once again. Then it worked.

@truemiller
Copy link

4. echo "test" | gpg --clearsign

this worked for me +1

@sankita15
Copy link

I just killed the gpg-agent and started again and it worked for me

killall gpg-agent
gpg-agent daemon

@0x61nas
Copy link

0x61nas commented Jan 12, 2023

thanks, @paolocarrasco

@Honglin-Lu
Copy link

There's another situation:

sec   dsa3072/AAAAAAAAAAAAA 2010-05-05 [SC] [expires: 2030-05-05]
      BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
uid                 [ultimate] Author Name <[email protected]>

While GitHub documentation operates with AAAAAAAAAAAAA in sections when you need to create and register the key in GPG, git requires BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB, i.e. git config --global user.signingkey BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB, instead of git config --global user.signingkey AAAAAAAAAAAAA

Hopefully, it helps someone.

This solution also works for me. Thank you!

@lfbharat
Copy link

omg I just need to run export GPG_TTY=$(tty)

  1. then use export GPG_TTY=$(tty)

this one worked for me as well.

@LuciNyan
Copy link

LuciNyan commented Feb 1, 2023

3. then use export GPG_TTY=$(tty)

Thank you! it works for me!

@livaper
Copy link

livaper commented Feb 15, 2023

Thank You, @paolocarrasco

@rootsongjc
Copy link

It works. Thank you!

@rahulsaw2003
Copy link

gpg: skipped "D6F50106F5C8A98B": No secret key
gpg: signing failed: No secret key
error: gpg failed to sign the data
fatal: failed to write commit object

I am getting this error since few days, I have regenerated the gpg key many times. but still I am getting this error. What should I do to get rid of this error. Please help as soon as possible.

@rahulsaw2003
Copy link

@exostin
After struggling for hours, I finally get rid of this error.
Thanks man

@kennethsequeira
Copy link

@NirajanMahara lifesaver!
Your solution worked out for me.

@thyarles
Copy link

thyarles commented Mar 8, 2023

I you're on WSL2, maybe this can help:

  • Add those lines to ~/.gnupg/gpg.conf

    use-agent 
    pinentry-mode loopback
    
  • Add this line to ~/.gnupg/gpg-agent.conf

    allow-loopback-pinentry
    

@gauravk-io
Copy link

gauravk-io commented Apr 4, 2023

I was getting the error

gpg: skipped "29D277CEFE65F74E": No secret key
gpg: signing failed: No secret key
error: gpg failed to sign the data
fatal: failed to write commit object

I just need to set the

gpg.program="C:\Program Files (x86)\GnuPG\bin\gpg.exe"

to

gpg.program=gpg

THANKYOU @victorjatoba

@Riessarius
Copy link

This exactly solved my problem. Great thanks! @victorjatoba

@renjujv
Copy link

renjujv commented Apr 24, 2023

@pro-akim
Copy link

pro-akim commented May 2, 2023

Thanks @paolocarrasco, you are awesome

@igorsobot
Copy link

I just killed the gpg-agent and started again and it worked for me

killall gpg-agent
gpg-agent daemon

Yes, sometimes pinentry-mac update brakes gpg-agent

@T410
Copy link

T410 commented May 12, 2023

Additionally, if you are using a mac and you are experiencing an issue, try step number 8: https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key?platform=mac

$ brew install pinentry-mac
$ echo "pinentry-program $(which pinentry-mac)" >> ~/.gnupg/gpg-agent.conf
$ killall gpg-agent

basically, it allows/forces your device to ask the password of the key

@DejavuMoe
Copy link

Super useful, thank you very much!

@ghdcksgml1
Copy link

Thanks :) @T410

@klubi
Copy link

klubi commented Jun 6, 2023

I'm running into similar issue, but It may be a layer deeper.
When I run gpg --status-fd=2 -bsau ... I get

[GNUPG:] PINENTRY_LAUNCHED 106 curses 1.1.0 - - -
gpg: signing failed: Inappropriate ioctl for device
[GNUPG:] FAILURE sign 83918950
gpg: signing failed: Inappropriate ioctl for device

I'm running that in jenkins, and I assume Jenkins is awaiting for passphrase input, but I can't seem to figure out how to sent it to it...

@ferdogan-nex
Copy link

ferdogan-nex commented Jun 12, 2023

This one worked for me. Thanks.

update: I just realised it didn't work.

@thyarles
Copy link

This one worked for me. Thanks.

Which one?

@klubi
Copy link

klubi commented Jun 12, 2023

I'm running into similar issue, but It may be a layer deeper. When I run gpg --status-fd=2 -bsau ... I get

[GNUPG:] PINENTRY_LAUNCHED 106 curses 1.1.0 - - -
gpg: signing failed: Inappropriate ioctl for device
[GNUPG:] FAILURE sign 83918950
gpg: signing failed: Inappropriate ioctl for device

I'm running that in jenkins, and I assume Jenkins is awaiting for passphrase input, but I can't seem to figure out how to sent it to it...

In case anyone runs into same issue, I ended up with below steps to import gpg key to Jenkins and use it to sign commits.

def call(String key_secret, String key_pass_secret, String key_id_secret, String key_grip_secret) {

    withCredentials([file(credentialsId: key_secret, variable: 'GPG_KEY'), 
    string(credentialsId: key_pass_secret, variable: 'GPG_KEY_PASS'),
    string(credentialsId: key_id_secret, variable: 'GPG_KEY_ID'),
    string(credentialsId: key_grip_secret, variable: 'GPG_KEY_GRIP')]) {
        sh """
            gpg --batch --passphrase $GPG_KEY_PASS --import $GPG_KEY
            echo allow-preset-passphrase > /root/.gnupg/gpg-agent.conf
            gpgconf --kill gpg-agent
            gpg-connect-agent -v
            \$(gpgconf --list-dirs libexecdir)/gpg-preset-passphrase --preset --passphrase $GPG_KEY_PASS $GPG_KEY_GRIP
            git config --global commit.gpgsign true
            git config --global user.signingkey $GPG_KEY_ID
            git config --global user.email "<REDACTED>"
            git config --global user.name "<REDACTED>”
        """
        }
}

to get key_grip run gpg —with-keygrip -K

All those shenanigans are caused by lack of tty in Jenkins thus there is no way to interactively input passphrase, so gpg-agent has to receive it as preset.
Killing and connecting back to agent is meant to solve two issues: updates to config, and race condition between agent startup and trying to exec proceeding command.

@ferdogan-nex
Copy link

This one worked for me. Thanks.

Which one?

Never mind, it actually didn't work. I still have the same issue.

@ferdogan-nex
Copy link

I got my issue solved. It was due to git version. Apparently git needs to be above 2.34 for code signing using SSH.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment