Common GnuPG problems and error messages, with fixes

Updated November 2026

Most GnuPG trouble comes down to a handful of messages. Find the message you see below, open the question, and follow the fix. All examples are for GnuPG 2.4 and 2.5 (2.5.24 is current as of November 2026); the wording of messages can differ slightly between versions.

Decrypting and verifying

"decryption failed: No secret key" – why can't I decrypt?

The message was encrypted to a key whose private part is not on this computer. GnuPG shows which key it needs:

gpg: encrypted with cv25519 key, ID D108F26C7C5C909B, created 2026-11-04
      "Alice Example <alice@example.org>"
gpg: public key decryption failed: No secret key
gpg: decryption failed: No secret key

Check the key ID against gpg -K --with-subkey-fingerprint (capital K lists private keys). Common causes: the sender used an old or wrong public key of yours; you created a new key and did not move the old private key to this machine; or the private key lives on a smartcard that is not plugged in. If the sender used the wrong key, send them your current public key and ask them to encrypt again. Nobody, including you, can decrypt the message without the matching private key.

How can I read messages I encrypted to someone else?

Only if you also encrypted them to yourself. Most mail programs do this automatically. On the command line, add yourself as a second recipient (-r you@example.org), or put this line in ~/.gnupg/gpg.conf so it always happens:

encrypt-to YOUR-FINGERPRINT

GnuPG's manual suggests giving a fingerprint here, not a name. Messages you already sent without this cannot be decrypted by you.

"Can't check signature: No public key" – what does it mean?

The signature may be fine, but you do not have the signer's public key, so GnuPG cannot check it. The output shows the fingerprint of the key that made the signature:

gpg:                using EDDSA key F5CBB616339D27659CF3A6A0DA9AA34BBCE56058
gpg: Can't check signature: No public key

Get that exact key from a source you trust (the project's website, the person, a keyserver, or Web Key Directory), import it with gpg --import, and verify again. Always fetch by the full fingerprint, never by a short ID. See message signatures for what the result means.

"no valid OpenPGP data found" – what is wrong with the file?

GnuPG did not find any OpenPGP packets in what you gave it. Typical causes: you downloaded an HTML page instead of the key or signature file (open it in a text editor to see); the file is empty or truncated; or you swapped the arguments when verifying. For a detached signature, the signature file comes first: gpg --verify file.sig file.

Encrypting to other people

"encryption failed: Unusable public key" – why can't I encrypt?

GnuPG found the recipient's key but will not use it. There are three usual reasons:

  • The key has expired or was revoked. Run gpg -k name@example.org and look for "expired" or "revoked". Refresh it (gpg --refresh-keys FINGERPRINT with a keyserver configured, or import a new copy from the owner) in case the owner has extended it. If it is really expired, ask the owner for a current key.
  • The key has no usable encryption subkey. Some keys can only sign. The owner must add an encryption subkey.
  • You are running in batch mode and the key is not validated. In that case GnuPG first prints "There is no assurance this key belongs to the named user". See the next question.
"There is no assurance this key belongs to the named user" – what should I do?

GnuPG is telling you that nothing in your keyring confirms that this key really belongs to that person. Anyone can create a key with any name and email address. Check the fingerprint with the owner by a channel you trust (in person, by phone, or on their official website). Then certify the key so GnuPG treats it as valid:

gpg --quick-lsign-key FINGERPRINT

A local signature (lsign) is stored only in your keyring and is never exported. Avoid the shortcut --trust-model always, which switches the check off for every key. Trust and certification are explained in key signatures and the web of trust.

Your own key

My own key has expired. Is it lost?

No. Expiry only stops others from using the key; you can extend it at any time with your private key and passphrase, even after the date has passed:

gpg --quick-set-expire FINGERPRINT 2y
gpg --quick-set-expire FINGERPRINT 2y '*'

The first line extends the primary key, the second extends all subkeys that are not revoked or already expired. A subkey that has already expired must be named by its own fingerprint instead of '*'. Then publish the updated public key again (keyserver, WKD, or send it to your contacts), because their copies still carry the old date. When you try to sign with an expired key, GnuPG reports "Unusable secret key".

"Bad passphrase" – I'm sure I typed it right

Check the keyboard layout, Caps Lock and any accented characters, which can be entered differently in a graphical and a terminal pinentry. If you changed the passphrase recently, the old one no longer works. If you really have forgotten it, there is no recovery and no back door: the private key is useless. Revoke the key with the revocation certificate GnuPG saved when you created it (in ~/.gnupg/openpgp-revocs.d/) and create a new one. See revoking a key.

Agent and pinentry

"signing failed: Inappropriate ioctl for device" – why no passphrase prompt?

GnuPG 2 does not read your passphrase itself. A background program, gpg-agent, asks for it through a small dialog program called pinentry. When you work in a terminal without a graphical desktop (for example over SSH), the agent does not know which terminal to use and fails with this message. The GnuPG manual says to add these lines to ~/.bashrc (or your shell's equivalent):

GPG_TTY=$(tty)
export GPG_TTY

Open a new shell and try again. On Windows this setting is not needed.

The passphrase dialog never appears, or gpg seems to hang

The agent may be stuck, or it may still remember an old display. Stop it; GnuPG starts a fresh one automatically the next time it is needed:

gpgconf --kill gpg-agent

Also check that a pinentry program is installed (your package manager has packages whose names start with pinentry), or choose one in ~/.gnupg/gpg-agent.conf with a line such as pinentry-program /usr/bin/pinentry-curses, then kill the agent again.

How do I give the passphrase to gpg automatically, for a script?

The old FAQ answered this with the PGPPASS environment variable, which put the passphrase where other programs could often read it. Today the better answers are, in order:

  1. Use a key without a passphrase that exists only for that job, on a locked-down machine, and that can do nothing else (for example a signing-only subkey for build artifacts).
  2. Let gpg-agent cache the passphrase. By default an entry stays valid for 600 seconds after its last use and at most 2 hours; you can change this with default-cache-ttl and max-cache-ttl in gpg-agent.conf.
  3. For unattended runs, use --batch --pinentry-mode loopback --passphrase-file FILE. The passphrase is then in a file, so protect that file as carefully as the key.
How can a script tell whether a gpg command worked?

Check the exit code. In our tests a good signature returns 0, a bad one returns 1, and other errors return 2. Do not parse the human-readable messages, which are translated and change between versions. For signature checks use gpgv or gpg --assert-signer FINGERPRINT --verify …; with --assert-signer, GnuPG exits with 0 only if a valid signature from that key was found.

Keyservers

"keyserver receive failed: No keyserver available"

Since GnuPG 2.5.3 there is no default keyserver, so --recv-keys and --search-keys fail until you choose one. Add a line to ~/.gnupg/dirmngr.conf, for example:

keyserver hkps://keys.openpgp.org

then run gpgconf --kill dirmngr so the change is read. Note that keys.openpgp.org only distributes a name and email address after the key owner has confirmed that address, and does not publish third-party signatures by default. A key without a confirmed address can come back with no user ID at all, and GnuPG may then refuse to import it. For a key belonging to an email address, gpg --locate-keys name@example.org also tries Web Key Directory.

Old commands with subkeys.pgp.net fail

The pgp.net keyserver network no longer runs. Instructions that still contain --keyserver subkeys.pgp.net, other old pool names, or apt-key adv --recv-keys need to be rewritten. What to use instead of subkeys.pgp.net gives a replacement for each old command, and APT repository keys covers the Debian and Ubuntu case.

Sources