How to Fix “Peer’s Certificate Issuer Not Recognized” Error When Sending Email via SMTP.Gmail.com in Bash Scripts


4 views

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