msmtp - uhop/dotfiles GitHub Wiki
msmtp is a lightweight SMTP client that drops in as a sendmail replacement. Periodic notification wrappers invoke sendmail, so msmtp is a prerequisite whenever you want email on failure or on non-empty reports โ see setup-periodic ยง Notification wrappers.
If sendmail is missing, setup-periodic refuses to install a task and prints the platform-specific install command. If ~/.msmtprc is missing, it warns but proceeds.
| Platform | Command |
|---|---|
| Debian/Ubuntu | sudo apt install msmtp msmtp-mta |
| Fedora/RHEL | sudo dnf install msmtp |
| macOS | brew install msmtp |
msmtp-mta (Debian only) installs the sendmail symlink โ pointer to /usr/bin/msmtp โ so wrappers that call sendmail work unchanged. On other platforms the package includes it.
Verify:
command -v sendmail # should print /usr/sbin/sendmail or similar
sendmail -V 2>&1 | head -1Configuration lives in ~/.msmtprc, which must be mode 0600 or msmtp will refuse to read it (the password line is plaintext unless you use a password command).
Per the no-secrets-in-repo rule, ~/.msmtprc is user-owned and not tracked by chezmoi. Copy it to new machines deliberately (e.g., with playbash put ~/.msmtprc host:, or the planned jot bundle flow).
# ~/.msmtprc
defaults
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile ~/.msmtp.log
account gmail
host smtp.gmail.com
port 587
from [email protected]
user [email protected]
password ****-****-****-**** # Gmail app password, not account password
account default : gmailCreate a Gmail app password (requires 2FA enabled on the account). Then:
chmod 600 ~/.msmtprcOn macOS the TLS trust store path differs โ use tls_trust_file /etc/ssl/cert.pem or install and point at the Homebrew ca-certificates bundle.
To keep the plaintext password out of the file:
account gmail
# ...
passwordeval secret-tool lookup service msmtp user [email protected] # Linux, libsecret
# or: passwordeval security find-generic-password -s msmtp -a [email protected] -w # macOSStore the secret once via your keychain tool of choice.
Quick end-to-end check (sends a real message):
printf 'Subject: msmtp test from %s\n\nHello from %s.\n' "$(hostname)" "$(hostname)" \
| sendmail [email protected]Server check only (no send):
msmtp --serverinfo --tls --tls-certcheck=off --host=smtp.gmail.com --port=587If a send fails, inspect the log:
tail -n 20 ~/.msmtp.logThe wrappers invoked by setup-periodic pipe a prepared message into sendmail and pass the recipient address from the NOTIFY_EMAIL environment variable (set by the systemd unit or launchd plist). Nothing is sent on a clean run; mail goes out only when:
-
notify-playbashโ the playbook exits non-zero orplaybash --reportemits non-empty output. -
notify-on-failureโ the wrapped command exits non-zero (captures and mails its stdout/stderr). -
notify-systemd-failureโ a unit failed; the wrapper pullsjournalctlcontext and mails it.
See Workflows: maintenance ยง Scheduled maintenance for the end-to-end setup path.
| Symptom | Cause / fix |
|---|---|
msmtp: account default not found |
No ~/.msmtprc, or no account default : <name> line. |
msmtp: the file must have no more than user read/write permissions |
chmod 600 ~/.msmtprc. |
authentication failed on Gmail |
Use an app password, not the account password. Confirm 2FA is on. |
tls_trust_file errors on macOS |
Point at /etc/ssl/cert.pem or $(brew --prefix)/etc/ca-certificates/cert.pem. |
| Wrapper ran but no mail arrived | Check the unit/plist has NOTIFY_EMAIL set (systemctl cat <unit> or the plist); check ~/.msmtp.log; check the destination spam folder. |
setup-periodic add fails with "sendmail not found" |
Install msmtp-mta (Debian) or the full msmtp package (others). |
For structural context on the notification pipeline see setup-periodic.