Mutt, NeoMutt and GnuPG: signed and encrypted email today

Updated November 2026

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.

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:

  1. The agent does not know your terminal. The GnuPG manual says to set GPG_TTY in every shell. Add this to ~/.bashrc:
    GPG_TTY=$(tty)
    export GPG_TTY
  2. The wrong pinentry. The Mutt manual warns that the plain tty pinentry does not work properly with Mutt. Use the curses one (or a GUI one on a desktop). Put this in ~/.gnupg/gpg-agent.conf:
    pinentry-program /usr/bin/pinentry-curses
    Then restart the agent with gpgconf --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:

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:

FlagMeaning
Ssigned, and the signature checked out
ssigned (not yet verified, or verification failed)
PPGP encrypted
Kcontains 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

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

Sources