Skip to content

Instantly share code, notes, and snippets.

@paolocarrasco
Last active November 22, 2024 15:43
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!

@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.

@empeje
Copy link

empeje commented Jun 22, 2023

5. 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).

This save my life 🔥

@gregorywaynepower
Copy link

On Windows 10 machine, I aligned my Local Git instance's username and email to my Github username and email.

The linchpin was taking the second line of gpg --list-secret-keys --keyid-format=LONG (the one below sec) and put that longer code as my user.signingkey for my git config.

@wushingmushine
Copy link

wushingmushine commented Jul 4, 2023

I haven't seen this one yet in thread so in case anyone else encounters it in a small terminal window:

With the same initial error and trace log I ran gpg --status-fd=2 -bsau <your GPG key> but it hung indefinitely with no output.
So I tried echo "test" | gpg --clearsign and got this error:

> echo "test" | gpg --clearsign                                          
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

test
gpg: signing failed: Screen or window too small
gpg: [stdin]: clear-sign failed: Screen or window too small

So turns out you can get this error if your terminal window is too small because the key passphrase box cannot pop up

Thanks @paolocarrasco and @truemiller for the pointers!

@ferpieklo
Copy link

I'm on Windows using the terminal and Gpg4Win (instead of Git Bash), and this helped me solve the gpg: signing failed: No secret key issue.

Make sure that git config gpg.program points to the gpg.exe file from the package by doing the following:

  1. Run where.exe gpg.
  2. If the output returns several executables, locate the one from Gpg4Win (by default, the path is C:\Program FIles (x86)\GnuPG\bin\gpg.exe.
  3. Run git config --global gpg.program <path/to/gpg/from/Gpg4Win>

(source here)

@psavarmattas
Copy link

psavarmattas commented Aug 4, 2023

Thanks so much for this @NirajanMahara . This worked like a charm!

@joespinelli7
Copy link

Thank you! Guided me perfectly through my issue and resolved within minutes :)

@Ahmedntc
Copy link

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
    

Tried pretty much everything and this was what worked for me, thank you!

@meerilahi
Copy link

Thanks
@gauravk-io

@gbdubs
Copy link

gbdubs commented Sep 3, 2023

Thank you!

@OverRevvv
Copy link

Thank you @gauravk-io , I did what you did and resolved the error.

@luiguip
Copy link

luiguip commented Sep 20, 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
  ```

Thanks, worked on WSL2.

@wlopez30
Copy link

echo "test" | gpg --clearsign

I haven't seen this one yet in thread so in case anyone else encounters it in a small terminal window:

With the same initial error and trace log I ran gpg --status-fd=2 -bsau <your GPG key> but it hung indefinitely with no output. So I tried echo "test" | gpg --clearsign and got this error:

> echo "test" | gpg --clearsign                                          
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

test
gpg: signing failed: Screen or window too small
gpg: [stdin]: clear-sign failed: Screen or window too small

So turns out you can get this error if your terminal window is too small because the key passphrase box cannot pop up

Thanks @paolocarrasco and @truemiller for the pointers!

Yup. This was it for me.
Thank you!

@Carlos-vargs
Copy link

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

  1. then use export GPG_TTY=$(tty)

I tried everything and found that comment, you saved me bro

@rosangelysreyes
Copy link

Thank you! It worked for me following each step ❤️

@lehaiquantb
Copy link

On MacOS, I have to install pinentry-mac to enter passphrase

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

@after-ephemera
Copy link

Thank you for this!

@sudoAlphaX
Copy link

I'm on Windows using the terminal and Gpg4Win (instead of Git Bash), and this helped me solve the gpg: signing failed: No secret key issue.

Make sure that git config gpg.program points to the gpg.exe file from the package by doing the following:

1. Run `where.exe gpg`.

2. If the output returns several executables, locate the one from Gpg4Win (by default, the path is C:\Program FIles (x86)\GnuPG\bin\gpg.exe.

3. Run `git config --global gpg.program <path/to/gpg/from/Gpg4Win>`

(source here)

This worked for me. Thank you very much.

@babud08
Copy link

babud08 commented Oct 25, 2023

I tried this method and still I'm getting this error while commit my changes.

$ git commit -S -m "workflow files commit"
error: cannot spawn gpg2: No such file or directory
error: gpg failed to sign the data
fatal: failed to write commit object

@sudoAlphaX
Copy link

@babud08 i think you have to set git global config for gpg.program

Find your gpg.exe path by using:
where gpg

and use Git Bash to configure the path
git config --global gpg.program <path>

@szympajka
Copy link

Thank you!

@jrgleason
Copy link

gpg --status-fd=2 -bsau F93581548CDBCCB7
[GNUPG:] KEY_CONSIDERED E4C9A7533D31D43B288E162FF93581548CDBCCB7 2
[GNUPG:] BEGIN_SIGNING H10

and it just hangs there.

@shellheim
Copy link

Dude, I just misspelled user.signingkey as user.signkey

@joshjud
Copy link

joshjud commented Nov 10, 2023

Thank you! My key was wrong. Working now.

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