Mutt, NeoMutt and GnuPG: signed and encrypted email today
To sign and encrypt mail in Mutt or NeoMutt, you need three things. First, a GnuPG key. Second, a working pinentry so gpg can ask for your passphrase. Third, about eight lines in your muttrc that turn on the GPGME backend. This page sets up all three, shows how to send and check signed and encrypted mail, and lists the mistakes that make it fail.
The classic Mutt-i, GnuPG and PGP HOWTO from 2000 is kept by the LDP at tldp.org. It covered PGP 2 and PGP 5, separate command lines for each, and procmail tricks. None of that is needed now. GnuPG does the cryptography, and Mutt talks to it through the GPGME library.
- 2.5.24current GnuPG release (2.5 stable series), as of November 2026
- 2026-06-30end of life of the GnuPG 2.4 series
- 2.4.3current Mutt release (9 October 2026)
- 2026-06-16latest NeoMutt release
Upstream GnuPG declared 2.5 the stable series in December 2025, and 2.4 reached end of life on 30 June 2026. As of November 2026, distributions still package 2.4: Debian 13 has 2.4.7, Ubuntu 26.04 has 2.4.8, and Fedora and Arch have 2.4.9. Their security teams patch those packages, so use your distribution's GnuPG unless you have a reason not to. Everything on this page works the same with 2.4 and 2.5.
Install the software
# Debian, Ubuntu
sudo apt install neomutt gnupg pinentry-curses # or: mutt
# Fedora
sudo dnf install neomutt gnupg2 pinentry # or: mutt
# Arch
sudo pacman -S neomutt gnupg pinentry
Mutt and NeoMutt read almost the same config. NeoMutt is a fork with extra features, and it renames a few variables (shown below). Check that your build has GPGME support: run mutt -v or neomutt -v and look for gpgme in the feature list.
Create your key
One command creates a primary key for signing and a subkey for encryption, valid for two years:
gpg --quick-generate-key "Ada Lovelace <ada@example.org>" default default 2y
gpg --list-secret-keys --keyid-format long ada@example.org
The default words let gpg pick its current recommended algorithms. gpg also writes a revocation certificate to ~/.gnupg/openpgp-revocs.d/. Copy it, and an export of your secret key (gpg --export-secret-keys --armor ada@example.org), to offline storage. If you lose the key, the certificate lets you tell the world to stop using it.
Note the 40-character fingerprint that --list-secret-keys prints. You will put it in your muttrc, and give it to people who want to check that a key is really yours.
Make the passphrase prompt work
gpg never asks for your passphrase itself. The gpg-agent asks through a pinentry program. In a terminal mail client, two things go wrong:
- The agent does not know your terminal. The GnuPG manual says to set
GPG_TTYin every shell. Add this to~/.bashrc:GPG_TTY=$(tty) export GPG_TTY - The wrong pinentry. The Mutt manual warns that the plain
ttypinentry does not work properly with Mutt. Use the curses one (or a GUI one on a desktop). Put this in~/.gnupg/gpg-agent.conf:
Then restart the agent withpinentry-program /usr/bin/pinentry-cursesgpgconf --kill gpg-agent. It starts again by itself when needed.
Test outside Mutt first: echo test | gpg --clearsign should show the passphrase dialog and then print a signed message.
Get your correspondents' keys
To encrypt to Bob, you need Bob's public key. With its default settings, gpg looks in your keyring and then asks Bob's mail domain through the Web Key Directory (WKD):
gpg --locate-keys bob@example.net
gpg --import bob.asc # if Bob sent you a key file
In Mutt, a mail that carries a key shows the K flag. Press Ctrl+K (<extract-keys>) to import it.
Check the fingerprint. Anyone can publish a key with Bob's address on it. Compare the fingerprint with Bob over a channel you already trust, such as in person, by phone, or on his signed website. Only then rely on the key.
Configure Mutt or NeoMutt
Add this to ~/.muttrc (Mutt), or to ~/.config/neomutt/neomuttrc (NeoMutt). Replace the fingerprint with yours:
# Use GnuPG through GPGME (Mutt's default is "no", NeoMutt's is "yes")
set crypt_use_gpgme = yes
# Your key: used for signing, and to encrypt a copy to yourself
set pgp_default_key = "<your-40-character-fingerprint>"
set pgp_self_encrypt = yes
set postpone_encrypt = yes
# Verify signatures on mail you read
set crypt_verify_sig = yes
# Encrypt automatically when keys for all recipients are known
set crypt_opportunistic_encrypt = yes
# Put the Subject inside the encrypted part (Mutt's default is "no")
set crypt_protected_headers_write = yes
# Answer encrypted mail encrypted and signed
set crypt_replyencrypt = yes
set crypt_replysignencrypted = yes
# Optional: sign everything you send
#set crypt_autosign = yes
For NeoMutt, write the reply settings with their new names: crypt_reply_encrypt, crypt_reply_sign and crypt_reply_sign_encrypted. Since 2021, NeoMutt lists the old spellings as renamed. Restart the client after changing crypt_use_gpgme. It only takes effect from the config file, not when you set it at Mutt's : prompt.
Do not also source the old gpg.rc file of pgp_*_command lines. That file is for Mutt's "classic mode", which runs gpg as a separate program and needs crypt_use_gpgme unset.
Send signed and encrypted mail
Write the message as usual. In the compose menu, press p to open the PGP options and choose encrypt, sign, or both. The header area of the compose screen shows the security setting you chose. Then press y to send. If you set crypt_opportunistic_encrypt, encryption switches on by itself whenever keys for all recipients are in your keyring.
Other useful keys:
Esc kin the compose menu attaches your public key, so others can import it.Ctrl+Fmakes gpg-agent forget the cached passphrase.Esc Pchecks a message for old-style inline PGP.
Mutt sends PGP/MIME, as defined in RFC 3156 (which updated the RFC 2015 that the old HOWTO cited). A signed mail is multipart/signed with an application/pgp-signature part. An encrypted one is multipart/encrypted. The GPGME backend cannot create old inline PGP messages. Every current client reads PGP/MIME, so you do not need inline PGP.
Read and check mail
In the message index, Mutt's flags tell you the state at a glance:
| Flag | Meaning |
|---|---|
S | signed, and the signature checked out |
s | signed (not yet verified, or verification failed) |
P | PGP encrypted |
K | contains a PGP public key |
When you open a signed message, Mutt shows a signature information block above the text. It names the key that signed the message and says whether the signature is good. A good signature from a key you never checked only proves that the mail came from that key, not from the person.
Autocrypt, the easy alternative
Both Mutt and NeoMutt support Autocrypt (set autocrypt = yes, which needs GPGME). Clients swap keys in mail headers and then encrypt automatically. It protects against passive snooping with no key management. It does not check identities, so for anything sensitive, still compare fingerprints.
Other clients
- Thunderbird has had OpenPGP built in since version 78. It uses the RNP library and its own key store, not GnuPG's, so import your key into Thunderbird with an armored export from gpg.
- Evolution uses your GPG keys. Set the key ID under the account's Security tab.
- KMail offers OpenPGP/MIME, inline OpenPGP and S/MIME in its composer.
All of these speak PGP/MIME, so they interoperate with Mutt. For protecting the machine that holds your secret key, see the Security HOWTO. The same key can also sign your code releases (software release practice).
Troubleshooting
- "No passphrase prompt", or the screen is garbled: set
GPG_TTY, switch topinentry-curses, and rungpgconf --kill gpg-agent. - "No matching keys found" when encrypting: the recipient's key is missing or expired. Run
gpg --locate-keyson the address. - Settings seem ignored: you are mixing classic-mode
pgp_*_commandlines with GPGME. Pick one. - Encrypted drafts you cannot read later: keep
pgp_self_encryptandpostpone_encrypton, so that copies are also encrypted to you. - Cron jobs: Mutt disables cryptography in batch mode, so you cannot sign mail sent from scripts this way. Sign with
gpgdirectly.
Sources
- GnuPG home page and news (2.5 stable, 2.5.24) and GnuPG download page (2.4 end of life 2026-06-30), gnupg.org
- OpenPGP key management (--quick-generate-key, revocation certificates), Operational GPG commands (--locate-keys) and GPG configuration options (--auto-key-locate), GnuPG manual
- Invoking gpg-agent (GPG_TTY) and gpg-agent options (pinentry-program), GnuPG manual
- The Mutt E-Mail Client (release news) and Mutt 2.4.3 manual (encryption and signing, variables, key bindings)
- NeoMutt and NeoMutt reference (variables and defaults)
- RFC 3156: MIME Security with OpenPGP
- Thunderbird OpenPGP, Mozilla Wiki; Setting up GPG keys, Evolution help; KMail composer window, KDE documentation
- GnuPG package versions: Debian 13, Ubuntu 26.04, Arch Linux, Fedora 44 (mdapi)