SN

MongoDB Backup Failure Email Alerts with Amazon SES

Catch silent MongoDB backup failures before they cost you data. Wire Amazon SES into your Ubuntu cron script for instant emails when dumps or S3 uploads fail.

5 min readUpdated August 24, 2026

In the previous post I set up the automated MongoDB → S3 backup I've been running on production Ubuntu boxes. But backups without monitoring are dangerous: if a backup quietly fails and nobody notices, the whole data-protection strategy fails silently with it. I learned this the hard way when a rotated IAM key broke S3 uploads for three days before I noticed — the cron ran, the log said "Starting backup", and no email ever arrived because there was no email path yet.

This guide bolts Amazon Simple Email Service (SES) onto that backup script so you get an instant email whenever a backup breaks.

Architecture

MongoDB

mongodump

Upload to S3

If failure occurs → Send email alert via Amazon SES

Step 1: Set up Amazon SES

  1. Log in to the AWS Console
  2. Open Amazon Simple Email Service (SES)
  3. Go to Verified identities
  4. Click Create identity
  5. Choose Email Address
  6. Enter the sender email (e.g. alerts@yourdomain.com)
  7. Click Create
  8. Verify the email from your inbox

Important: If SES is in Sandbox mode you must also verify the recipient email. For production, request Production Access inside SES.

Step 2: Add SES permission to the IAM user

Go to IAM → Users → select your backup IAM user → Attach policy and attach:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["ses:SendEmail", "ses:SendRawEmail"],
      "Resource": "*"
    }
  ]
}

This lets the server send emails through SES.

Step 3: Test SES from the Ubuntu server

aws ses send-email \
  --from alerts@yourdomain.com \
  --destination ToAddresses=your@email.com \
  --message "Subject={Data=SES Test Email},Body={Text={Data=Amazon SES is working successfully}}" \
  --region ap-south-1

If configured correctly, you should receive the test email. If you see an error, check:

  • Verified email identities
  • IAM permissions
  • The correct AWS region

Step 4: Update the MongoDB backup script

Edit the script from the previous post:

nano ~/mongo-backup.sh

Replace its contents with:

#!/bin/bash
 
# Same `snap run aws-cli.aws` approach as the previous post — see there for the cron/PATH rationale.
 
MONGO_URI="mongodb://localhost:27017/mydatabase"
BACKUP_DIR="$HOME/bkp"
DATE=$(date +"%Y-%m-%d_%H-%M-%S")
S3_BUCKET="s3://your-bucket-name"
BACKUP_NAME="backup-$DATE.gz"
RETENTION_DAYS=7
 
SES_FROM="alerts@yourdomain.com"
SES_TO="your@email.com"
AWS_REGION="ap-south-1"
 
LOG_FILE="$HOME/mongo-backup.log"
 
send_failure_email() {
  snap run aws-cli.aws ses send-email \
    --from "$SES_FROM" \
    --destination ToAddresses="$SES_TO" \
    --message "Subject={Data=Mongo Backup FAILED},Body={Text={Data=Backup failed on $(hostname) at $DATE. Check logs at $LOG_FILE}}" \
    --region "$AWS_REGION"
}
 
mkdir -p "$BACKUP_DIR"
 
echo "Starting backup: $DATE" >> "$LOG_FILE"
 
# Run mongodump
mongodump --uri="$MONGO_URI" \
  --archive="$BACKUP_DIR/$BACKUP_NAME" --gzip >> "$LOG_FILE" 2>&1
 
if [ $? -ne 0 ]; then
  echo "Mongo dump failed" >> "$LOG_FILE"
  send_failure_email
  exit 1
fi
 
# Upload to S3
snap run aws-cli.aws s3 cp "$BACKUP_DIR/$BACKUP_NAME" "$S3_BUCKET/" >> "$LOG_FILE" 2>&1
 
if [ $? -ne 0 ]; then
  echo "S3 upload failed" >> "$LOG_FILE"
  send_failure_email
  exit 1
fi
 
# Cleanup old local backups
find "$BACKUP_DIR" -type f -mtime +$RETENTION_DAYS -delete
 
echo "Backup completed successfully: $BACKUP_NAME" >> "$LOG_FILE"

Step 5: Make the script executable

chmod +x ~/mongo-backup.sh

How it works

  • If mongodump fails → email is sent
  • If S3 upload fails → email is sent
  • If everything succeeds → no email is sent

You only hear from the script when something is wrong, which is exactly what you want from monitoring.

Production best practices

  • Use an IAM role instead of access keys if running on EC2
  • Restrict SES permissions to specific verified identities
  • Add an S3 lifecycle rule for automatic cleanup
  • Periodically test the restore process — a backup you've never restored is not a backup
  • Review backup logs weekly

FAQ

Why SES and not SNS or a Slack webhook? SES is the cheapest option (~$0.10 per 1,000 emails) and doesn't need a topic subscription like SNS. For a solo dev inbox that fires a few times a year, this is fine. If your team already lives in Slack, swap the send_failure_email function for a curl to an incoming webhook — same pattern, different transport.

Why doesn't the script use set -e? Because I want to catch the failure, log it, and email — not exit silently. set -e would short-circuit before send_failure_email runs. Explicit $? checks after each command give me that control.

What if SES itself is down when I try to send the alert? Rare, but possible. The email attempt writes to the log either way, so a grep -i fail ~/mongo-backup.log on your weekly review catches anything the email path missed. For paranoia, tail the log into a second channel (Papertrail, Loki, CloudWatch Logs).

How do I stop getting spammed if the backup fails every night? Add a "sent today" flag: touch ~/.mongo-backup-alert-sent inside send_failure_email and short-circuit the function if the flag file is less than 24 h old. Delete the flag on the next successful run.

Can I use Gmail SMTP instead of SES? You can, but Gmail throttles hard on scripted senders and revokes app passwords aggressively. SES with a verified domain is more reliable for unattended alerting.

Final result

You now have:

  • Automated MongoDB backup
  • Cloud storage in S3
  • Automatic failure detection
  • Email alert system
  • Production-ready monitoring

What's next

Backups and alerts get you two-thirds of the way. The part everyone skips: actually restoring. In the next post I restore one of these archives from S3 into a scratch database, verify it, and set up a quarterly restore drill — because a backup you've never restored is not a backup.