GoReleaser GPG "signing failed" in CI
GoReleaser can sign checksums and artifacts with GPG. Signing fails in CI when the private key was never imported into the runner keyring, or when gpg prompts for a passphrase it cannot get non-interactively.
What this error means
GoReleaser fails at the sign step with "signing failed" and a gpg error such as "No secret key" or "Inappropriate ioctl for device".
Terminal
⨯ sign failed error=sign: signing failed: exit status 2:
gpg: signing failed: No secret keyCommon causes
The signing key is not imported
The private key is not in the runner keyring, so gpg has no secret key to sign with.
gpg cannot read the passphrase
Without --batch and --pinentry-mode loopback, gpg tries to prompt on a tty that CI does not have.
How to fix it
Import the key and configure batch signing
- Store the exported private key as a secret and import it in a setup step.
- Provide the passphrase via a secret and loopback pinentry.
- Point the sign config at the imported key.
.goreleaser.yaml
signs:
- artifacts: checksum
args:
- "--batch"
- "--pinentry-mode=loopback"
- "--passphrase=${GPG_PASSPHRASE}"
- "--sign"Import the secret key before GoReleaser
Load the private key into gpg so a secret key is available at sign time.
Terminal
echo "${{ secrets.GPG_PRIVATE_KEY }}" | gpg --batch --importHow to prevent it
- Import the signing key in a dedicated setup step.
- Use
--batchand loopback pinentry for non-interactive gpg. - Keep the key and passphrase in secrets, never in the repo.
Related guides
GoReleaser cosign signing failed in CIFix GoReleaser cosign signing failures in CI - keyless signing needs id-token permission and OIDC, or a key f…
GoReleaser nfpm rpm/deb packaging failed in CIFix GoReleaser nfpm packaging failures in CI - building rpm or deb packages fails when required fields are mi…
GoReleaser "failed to build/push docker image" in CIFix GoReleaser Docker image build and push failures in CI - the registry login is missing, so the push is den…