When trying to send emails through smtp.gmail.com using command-line tools like mailx in bash scripts, many developers encounter the frustrating certificate error:
Error in certificate: Peer's certificate issuer is not recognized
This occurs because your system doesn't inherently trust Google's certificate authority. While the email might still go through (due to security downgrade fallbacks), this warning indicates potential security vulnerabilities.
Google uses certificates issued by their own Google Internet Authority. Many Linux systems don't include this CA by default in their NSS certificate database (used by mailx and other tools).
You can check your current certificates with:
certutil -L -d /path/to/certs
If you see "Google Internet Authority" with empty trust attributes (,,), that's the root cause.
Here's how to properly configure certificate trust for Gmail SMTP:
# 1. Export the existing certificate (if present)
certutil -L -n 'Google Internet Authority' -d /path/to/certs -a > google.cert.asc
# 2. If not present, download Google's root certificate:
wget -O google.cert.asc https://pki.goog/roots/roots.pem
# 3. Import with proper trust flags
certutil -A -t "C,," -n 'Google Internet Authority' -d /path/to/certs -i google.cert.asc
# 4. Verify
certutil -L -d /path/to/certs | grep 'Google Internet Authority'
For those who can't modify system certificates:
# 1. Use openssl s_client to test connection:
openssl s_client -connect smtp.gmail.com:465 -showcerts
# 2. Configure mailx to ignore certificate errors (NOT recommended)
echo "set ssl-verify=ignore" >> ~/.mailrc
For production scripts, consider this more robust approach:
#!/bin/bash
send_alert() {
if ! mailx -v -A gmail -s "Alert: $1" admin@example.com > mail.log 2>&1; then
# Fallback to curl if mailx fails
curl --ssl-reqd --url 'smtps://smtp.gmail.com:465' \
--user 'user@gmail.com:apppassword' \
--mail-from 'user@gmail.com' \
--mail-rcpt 'admin@example.com' \
--upload-file - <<EOF
From: Script Alert <user@gmail.com>
To: Admin <admin@example.com>
Subject: Alert: $1
$2
EOF
fi
}
- Never store plaintext passwords in scripts
- Use app passwords instead of main Google account passwords
- Consider using OAuth2 authentication where possible
- Regularly check certificate expiration dates
When automating email notifications through bash scripts using Gmail's SMTP server (smtp.gmail.com), many developers encounter the frustrating certificate error:
Error in certificate: Peer's certificate issuer is not recognized
This occurs because the system's certificate store doesn't automatically trust Gmail's certificate chain. While the emails may still go through (due to most clients ignoring such warnings), proper certificate validation is crucial for security.
The issue stems from how mailx (or other command-line mail utilities) handles SSL/TLS certificate validation:
- Gmail uses certificates issued by Google's own CA (Certificate Authority)
- Many Linux systems don't include Google's root certificates by default
- The NSS certificate database (used by mailx) needs explicit trust configuration
Here's the complete solution I discovered after much trial and error:
First, check if the Google certificate exists in your system's NSS database:
certutil -L -d ~/.certs
# Sample output showing untrusted certificate:
# Google Internet Authority ,,
Export the certificate to a PEM file:
certutil -L -n 'Google Internet Authority' -d ~/.certs -a > google.cert.pem
Re-import it with proper trust flags:
certutil -A -t "C,," -n 'Google Internet Authority' -d ~/.certs -i google.cert.pem
If the certificate isn't in your system's store, you can fetch it directly:
# Using OpenSSL to get the certificate chain
openssl s_client -connect smtp.gmail.com:465 -showcerts 2>/dev/null | \
awk '/BEGIN CERT/,/END CERT/{ if(/BEGIN CERT/){a++}; out="cert"a".pem"; print >out}'
# Then import each relevant certificate
certutil -A -t "C,," -n 'Gmail SMTP' -d ~/.certs -i cert1.pem
Your .mailrc should include these settings:
set smtp-use-starttls
set smtp=smtp://smtp.gmail.com:587
set smtp-auth=login
set smtp-auth-user=yourname@gmail.com
set smtp-auth-password=yourpassword
set nss-config-dir=/home/user/.certs
set ssl-verify=strict
After configuration, test with:
echo "Test message" | mailx -v -s "SMTP Test" -S smtp-use-starttls -S smtp=smtp://smtp.gmail.com:587 recipient@example.com
Check your certificate trust settings again:
certutil -L -d ~/.certs
# Should now show:
# Google Internet Authority C,,
For robust scripting, add certificate verification:
#!/bin/bash
send_alert() {
if ! mailx -A gmail -s "$1" admin@company.com >/dev/null 2>&1; then
echo "Failed to send alert: $1" >&2
return 1
fi
return 0
}
# Usage example
if ! check_system_health; then
send_alert "System health check failed"
fi