エラーメッセージ
gpg: signing failed: Inappropriate ioctl for device
別の表記
- [GNUPG:] FAILURE sign 83918950
Git はこれを「error: gpg failed to sign the data」の下に表示します。`--status-fd` を指定すると、gpg は `[GNUPG:] FAILURE sign 83918950`(この状態を表す GPG の数値エラーコード)も出力します。
Git commit signing with GnuPG 2 — pinentry has no terminal
このエラーの意味
署名鍵はパスフレーズで保護されており、gpg-agent はパスフレーズを尋ねるためにターミナル用の pinentry を起動しましたが、pinentry がターミナルを開けませんでした。「Inappropriate ioctl for device」は OS の `ENOTTY` で、stdin が TTY ではなく、`GPG_TTY` も TTY を指定していないことを示します。鍵と設定には問題がなく、失敗したのはパスフレーズの入力プロンプトだけです。
発生する理由
GPG_TTY がエクスポートされていない
よくあるGnuPG のドキュメントでは、シェルのプロファイルに `export GPG_TTY=$(tty)` を記述することが必須とされています。これがないと、curses 版の pinentry はプロンプトをどこに表示すればよいかわかりません。
IDE や GUI クライアントから署名している
よくあるVS Code、JetBrains の IDE、GUI の Git クライアントは、ターミナルなしで git を実行します。ターミナル専用の pinentry(`pinentry-curses`、`pinentry-tty`)は、そこでは動作できません。
パスフレーズで保護された鍵を使って CI で署名している
ときどきパスフレーズを入力する人がいません。CI には、専用の鍵と、パスフレーズを非対話的に渡す方法が必要です。
修正方法
- 1.
GPG_TTY をエクスポートする
シェルのプロファイルに追加してください。実行中のエージェントが別のターミナルから起動されている場合は、`updatestartuptty` でエージェントを更新してください。
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.
グラフィカルな pinentry を使う
`pinentry-mac`、`pinentry-gnome3`、`pinentry-qt` はダイアログを表示するため、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
`allow-loopback-pinentry` を設定すると、gpg はパスフレーズをファイルから読み込めます。CI 専用の署名専用鍵を使い、個人の鍵は決して使わないでください。
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
関連するエラー
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)