本文へスキップ
ecdsa.com
Git commit signing with GnuPG 2Git

エラーメッセージ

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 を指定していないことを示します。鍵と設定には問題がなく、失敗したのはパスフレーズの入力プロンプトだけです。

発生する理由

修正方法

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

関連するエラー

署名エラーデータベースをすべて見る