Mensaje de error
gpg: signing failed: Inappropriate ioctl for device
También se muestra como
- [GNUPG:] FAILURE sign 83918950
Git lo imprime debajo de «error: gpg failed to sign the data». Con `--status-fd`, gpg también emite `[GNUPG:] FAILURE sign 83918950` (el código de error numérico de GPG para esta situación).
Git commit signing with GnuPG 2 — pinentry has no terminal
Qué significa
La clave de firma está protegida con una frase de contraseña, gpg-agent lanzó un pinentry de terminal para pedirla y pinentry no pudo abrir una terminal. «Inappropriate ioctl for device» es el `ENOTTY` del sistema operativo: stdin no es una TTY y `GPG_TTY` no indica ninguna. La clave y la configuración están bien; solo falló la solicitud de la frase de contraseña.
Por qué ocurre
GPG_TTY no está exportada
frecuenteLa documentación de GnuPG exige `export GPG_TTY=$(tty)` en el perfil de la shell. Sin ello, el pinentry de curses no sabe dónde mostrar la solicitud.
Firma desde un IDE o un cliente gráfico
frecuenteVS Code, los IDE de JetBrains y los clientes gráficos de Git ejecutan git sin terminal. Un pinentry solo para terminal (`pinentry-curses`, `pinentry-tty`) no puede funcionar ahí.
Firma en CI con una clave protegida por frase de contraseña
ocasionalNo hay ninguna persona que escriba la frase de contraseña. La CI necesita una clave dedicada y una forma no interactiva de proporcionar la frase de contraseña.
Cómo solucionarlo
- 1.
Exportar GPG_TTY
Añádela al perfil de tu shell; actualiza el agente en ejecución con `updatestartuptty` si se inició desde otra 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 un pinentry gráfico
`pinentry-mac`, `pinentry-gnome3` o `pinentry-qt` muestran un cuadro de diálogo, que también funciona en los IDE.
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 en modo loopback para la automatización
Con `allow-loopback-pinentry`, gpg puede leer la frase de contraseña desde un archivo. Usa una clave solo de firma dedicada a la CI, nunca una clave personal.
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
Errores 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)