gpg: decryption failed: No secret key. What It Means, and the Four Causes
The message reads:
gpg: decryption failed: No secret key
Almost everyone reads it as “my key is broken”. It says something narrower and more useful: the private key able to open this file is not in the keyring GPG is currently reading. The file is fine. Your key may be fine too. They are simply not in the same place.
Everything below follows from that one distinction.
First, find out which key the file is asking for
Before changing anything, ask the file:
gpg --list-packets encrypted-file.gpg
Near the top you get a line like:
:pubkey enc packet: version 3, algo 1, keyid 3AA5C34371567BD2
That key ID is the answer to the whole problem. The file was encrypted to that specific key, and only its private half can open it.
Now ask your keyring whether it holds that private half:
gpg --list-secret-keys
If the ID from the file does not appear here, GPG is telling the exact truth. What remains is to find out why.
One detail catches people out: --list-packets on an old file may show
keyid 0000000000000000. That is a hidden recipient, encrypted with --throw-keyids or
--hidden-recipient. GPG will then try every private key you have, and the same error means none of
them worked.

Cause 1: you are reading the wrong keyring
This is the most common cause, and the easiest to miss because nothing looks wrong.
sudo gpg reads root’s keyring, not yours. A cron job runs as another user. A container has an
empty ~/.gnupg. In every case the key exists, three metres away, in a directory this process is
not looking at.
gpg --version | grep Home
echo $GNUPGHOME
The first line prints the home directory actually in use. If it is not the one holding your key, that is the bug, and the fix is to run as the right user rather than to import anything.
Cause 2: you have the public key, not the private one
Exporting a key without --export-secret-keys produces a public key only, and importing it gives
you an entry in --list-keys and nothing in --list-secret-keys.
The result is a keyring that looks correct at a glance and cannot decrypt anything. If the key ID appears in the first list and not in the second, this is your cause. The private half has to be exported again, from the machine that has it:
gpg --export-secret-keys --armor KEYID > private.asc
Treat that file the way you would treat the key itself, because it is the key itself. Not in a chat message, not in a synced folder, deleted once imported.
Cause 3: the file was encrypted to someone else’s key
Encryption is one directional. A file encrypted to a colleague’s public key can be opened by that colleague and by nobody else, including the person who created it.
This surprises people who encrypt their own backups and later find they cannot read them. If you want to be able to open what you encrypt, add yourself as a recipient:
gpg --encrypt --recipient colleague@example.com --recipient me@example.com file
Setting default-recipient-self in ~/.gnupg/gpg.conf makes that automatic. There is no recovery
path if this is your cause and the other party is unavailable. That is the design, not a defect.
Cause 4: the private key is on a smartcard or YubiKey that is not present
With a hardware key, --list-secret-keys shows a stub marked ssb> with a > character. The
stub is a pointer, not a key. If the device is not plugged in, or scdaemon cannot reach it, GPG
reports exactly the same message.
gpg --card-status
If that fails, the problem is the card reader or the daemon rather than the keyring. Restarting the agent is the usual first move:
gpgconf --kill gpg-agent
The one that is not on this list, and why
A wrong passphrase does not produce this error. It produces Bad passphrase or Bad session key. If you are seeing No secret key, GPG never reached the point of asking for a passphrase,
because it never found a key to ask about. Reinstalling GPG, clearing the agent cache, or trying
your password again will do nothing for it.
That is worth stating plainly, because it is the most common wasted hour on this error.
Keeping it from happening again
- Export and store the private key before you need it, encrypted, somewhere you will still have access to in two years. A key that exists only on a laptop is one spilled coffee from being gone.
- Add yourself as a recipient by default, so anything you encrypt stays readable by you.
- Write down which key ID protects which archive. A key ID in a note costs nothing and saves the
--list-packetsstep at the worst possible moment.
The broader picture of how these keys relate to each other is in GPG vs PGP, and using them for mail rather than files is covered in how to encrypt email.