title: 'Git: gpg failed to sign the data' in visual studio code
body: <p>After a fresh Linux install I'm trying to set up my environment and I keep getting the <code>Git: gpg failed to sign the data</code> error upon committing changes locally.  I'm using Visual Studio Code, proprietary, not opensource version.</p>
  
  <p>.gitconfig:</p>
  
  <pre><code>[user]
      name = djweaver-dev
      email = djweaver@djweaver.dev
      signingkey = 37A0xxxx...
  [core]
      excludesfile = /home/dweaver/.gitignore_global
  [commit]
      gpgSign = true
  </code></pre>
  
  <p>yikes. furthermore <strong>I can't find a way to copy the output log nor can I find where that log is</strong> so here is a pic:</p>
  
  <p><a href="https://i.stack.imgur.com/pgWif.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/pgWif.jpg" alt="output log"></a></p>
  
  <p><strong>Steps I have taken so far:</strong></p>
  
  <ul>
  <li>generated new key (RSA 4096) in gnugp </li>
  <li>added signing key to global .gitconfig  </li>
  <li>set <code>"git.enableCommitSigning": true</code> in Visual Studio Code settings  </li>
  <li><strong>cloned</strong> my repo from github  </li>
  </ul>
  
  <p>Typically when I commits in the past I would get a dialog box requesting GPG authentication upon commit.  I do not get this now, just the error dialog.</p>
  
  <p><strong>UPDATE:</strong> Okay now I'm <em>really</em> confused.  I restarted vscode (not the first time I've done this in this process) and voilà, it works.  Only thing I can think of is maybe I biffed the directory somehow?  Either way, it works now.</p>
  
  <p><strong>UPDATE:</strong> Oddly, I'm back to this same issue almost a month later after a fresh arch install.  I've tried everything that I've been able to find on this site, and <em>nothing</em> works.  </p>
  
  <p>I've tried adding <code>export GPG_TTY=$(tty)</code> to .bash_profile, and also .bashrc</p>
  
  <p><strong>Git log:</strong></p>
  
  <pre><code>Looking for git in: git
  Using git 2.26.2 from git
  &gt; git rev-parse --show-toplevel
  &gt; git rev-parse --git-dir
  Open repository: /home/dw/dev/website
  &gt; git status -z -u
  &gt; git symbolic-ref --short HEAD
  &gt; git rev-parse master
  &gt; git rev-parse --symbolic-full-name master@{u}
  &gt; git rev-list --left-right master...refs/remotes/origin/master
  &gt; git for-each-ref --format %(refname) %(objectname) --sort -committerdate
  &gt; git remote --verbose
  Failed to watch ref '/home/dw/dev/website/.git/refs/remotes/origin/master', is most likely packed.
  Error: ENOENT: no such file or directory, watch '/home/dw/dev/website/.git/refs/remotes/origin/master'
      at FSWatcher.start (internal/fs/watchers.js:165:26)
      at Object.watch (fs.js:1270:11)
      at Object.t.watch (/usr/lib/code/extensions/git/dist/main.js:1:604919)
      at T.updateTransientWatchers (/usr/lib/code/extensions/git/dist/main.js:1:83965)
      at e.fire (/usr/lib/code/out/vs/workbench/services/extensions/node/extensionHostProcess.js:46:87)
      at e.updateModelState (/usr/lib/code/extensions/git/dist/main.js:1:103179)
  &gt; git config --get commit.template
  &gt; git check-ignore -v -z --stdin
  &gt; git check-ignore -v -z --stdin
  &gt; git commit --quiet --allow-empty-message --file - -S
  error: gpg failed to sign the data
  fatal: failed to write commit object
  &gt; git config --get-all user.name
  &gt; git config --get-all user.email
  </code></pre>
  
  <p>Same config as last time, <code>user.name</code> and <code>user.email</code> both match each key I've been trying it with... <code>user.signingkey</code> matches.  Not sure where else to go with this one, as I've tried it across newly initialized local repos as well as repos that I've pulled from github both with official MS vscode (AUR) and OSS version, in the vscode terminal emulator as well as gnome terminal with same results so it <em>has</em> to be either a git thing or a gnugp thing. </p>
  
  <p>What I have noticed is that after committing without signing, it will work immediately after: I get prompted for my key passphrase the first time, then it works on subsequent commits until a seemingly random number of minutes later, <strong>it just doesn't work</strong> anymore and the process has to be repeated.</p>
  
  <p>There were a few macos users posting about having a stalled <code>gpg-agent</code> running in the background and it fixed it for them, however, I am seeing:</p>
  
  <pre><code>[dw@dwLinux website]$ gpg-agent
  gpg-agent[2870]: gpg-agent running and available
  </code></pre>
  
  <p>Whats interesting also is that by doing <code>echo "test" | gpg --clearsign</code> I get the same results: it works for a short period of time, then I can't sign anymore.</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Okay so day number 2 of trying to fix this.  To rule out the gpg-agent theory as described <a href="https://stackoverflow.com/a/44303808/13119325">here</a> I followed the instructions on how to reload gpg-agent using the <code>$ gpg-connect-agent reloadagent /bye</code> command demonstrated on the <a href="https://wiki.archlinux.org/index.php/GnuPG#Reload_the_agent" rel="noreferrer">Arch Linux Wiki</a></p>
  
  <p><strong>This had no effect</strong></p>
  
  <p>So being that I can reproduce this problem across vscode official, oss code, and vscodium, as well as bash, I thought <strong>maybe this was a permissions related issue, as so many problems with linux typically are</strong>.  I added my user to all kinds of groups, including root, and <strong>this also had no effect</strong> so I think I can safely rule out the following:</p>
  
  <ul>
  <li>VS Code</li>
  <li>GnuGP</li>
  <li>gpg-agent</li>
  <li>Linux permissions</li>
  </ul>
  
  <p>So my next focus was the config files themselves, but as has been stated before the credentials match the key in <code>.gitconfig</code> and my <code>.bash_profile</code> has been correctly configured with <code>export GPG_TTY=$(tty)</code>.</p>
  
  <p><strong>An interesting note on this from the official <a href="https://www.gnupg.org/(it)/documentation/manuals/gnupg/Common-Problems.html" rel="noreferrer">GnuPG docs</a> shows a syntax discrepency between their way, and the way you are instructed to append this to .bash_profile on the GitHub docs <a href="https://help.github.com/en/github/authenticating-to-github/telling-git-about-your-signing-key" rel="noreferrer">here</a></strong></p>
  
  <blockquote>
    <p><strong>From GnuPG:</strong> "The far most common reason for this is that the environment variable GPG_TTY has not been set correctly. Make sure that it has been set to a real tty device and not just to ‘/dev/tty’; i.e. ‘GPG_TTY=tty’ is plainly wrong; what you want is ‘GPG_TTY=tty’ — note the back ticks. Also make sure that this environment variable gets exported, that is you should follow up the setting with an ‘export GPG_TTY’"</p>
  </blockquote>
  
  <p>As I understood <code>$(whatever)</code> in bash was to execute a command, but for safe measure I've appended .bash_profile using both ways and <strong>neither solved the issue.</strong></p>
  
  <p><strong>One last thing</strong></p>
  
  <p>In <a href="https://stackoverflow.com/a/51782673/13119325">this post</a> the user talks about gpg-agent authentication not being available when daemonized and gpg access is being initiated by another application (such as an IDE like VSCode), which explains how I could <em>temporarily</em> sign commits after committing a random file or doing <code>echo "test" | gpg --clearsign</code> and being authenticated... but alas like most other 'solutions' to this topic, they reveal that all they had to do in the end was add <code>export GPG_TTY=$(tty)</code> to their .bash_profile, which I have already tried.</p>
  
  <p><strong>Where to go from here?</strong></p>
  
  <p>I still can't explain why it worked on my previous install, and frankly, not a whole lot has changed afaik.  I typically do fresh installs often and keep a pretty minimal arch linux build with lts kernel each time w/base-devel and nodejs/python/git/vscode/firefox/discord is pretty much my entire workflow.  <strong>I'm all out of ideas.</strong></p>