Mensagem de erro
gpg: signing failed: Inappropriate ioctl for device
Também aparece como
- [GNUPG:] FAILURE sign 83918950
O Git o imprime abaixo de “error: gpg failed to sign the data”. Com `--status-fd`, o gpg também emite `[GNUPG:] FAILURE sign 83918950` (o código numérico de erro do GPG para essa condição).
Git commit signing with GnuPG 2 — pinentry has no terminal
O que significa
A chave de assinatura é protegida por uma frase secreta, o gpg-agent iniciou um pinentry de terminal para pedi-la e o pinentry não conseguiu abrir um terminal. “Inappropriate ioctl for device” é o `ENOTTY` do sistema operacional: o stdin não é um TTY e `GPG_TTY` não indica nenhum. A chave e a configuração estão corretas; só o pedido da frase secreta falhou.
Por que acontece
A variável GPG_TTY não foi exportada
comumA documentação do GnuPG exige `export GPG_TTY=$(tty)` no perfil do shell. Sem isso, o pinentry curses não sabe onde exibir o pedido da frase secreta.
Assinatura a partir de uma IDE ou de um cliente gráfico
comumO VS Code, as IDEs da JetBrains e os clientes gráficos de Git executam o git sem terminal. Um pinentry só de terminal (`pinentry-curses`, `pinentry-tty`) não funciona ali.
Assinatura no CI com uma chave protegida por frase secreta
ocasionalNão há ninguém para digitar a frase secreta. O CI precisa de uma chave dedicada e de uma forma não interativa de fornecer a frase secreta.
Como corrigir
- 1.
Exportar GPG_TTY
Adicione a variável ao perfil do shell; atualize o agente em execução com `updatestartuptty` se ele tiver sido iniciado em outro terminal.
bash # ~/.bashrc or ~/.zshrc export GPG_TTY=$(tty) # if gpg-agent was started before, tell it about the current terminal gpg-connect-agent updatestartuptty /bye - 2.
Usar um pinentry gráfico
`pinentry-mac`, `pinentry-gnome3` ou `pinentry-qt` mostram uma caixa de diálogo, o que funciona também em IDEs.
bash # macOS (Homebrew): a GUI pinentry works for IDEs and GUI Git clients too brew install pinentry-mac echo "pinentry-program $(brew --prefix)/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf gpgconf --kill gpg-agent - 3.
Pinentry loopback para automação
Com `allow-loopback-pinentry`, o gpg pode ler a frase secreta de um arquivo. Use uma chave dedicada ao CI e só para assinatura, nunca uma chave pessoal.
bash # CI: a dedicated signing key; passphrase supplied non-interactively via loopback pinentry echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf && gpgconf --kill gpg-agent cat > /usr/local/bin/gpg-ci <<'EOF' #!/bin/sh exec gpg --batch --pinentry-mode loopback --passphrase-file "$GPG_PASSPHRASE_FILE" "$@" EOF chmod +x /usr/local/bin/gpg-ci git config --global gpg.program gpg-ci
Erros relacionados
error: gpg failed to sign the dataGit (commit -S, tag -s, commit.gpgsign) with GnuPGsign_and_send_pubkey: signing failed for RSA "/path/to/key" from agent: agent r…OpenSSH client with an SSH agent (ssh-agent, gpg-agent, 1Password, Secretive, Windows OpenSSH agent)gpg: Can't check signature: No public keyGnuPG (gpg --verify, git verify-commit / verify-tag / log --show-signature)