Home / OCI

OCITroubleshootingIntermediate

OCI Email Delivery: emails not arriving, SMTP 535 errors and suppressed recipients

Work out whether mail failed at submission, was suppressed or bounced, then fix SMTP credentials, approved senders, DKIM, port and limit problems.

Deepak Bhardwaj7 min read

Applies toOCI Email Delivery (SMTP and HTTPS submission), OCI Logging, OCI CLI 3.x

Symptom

An application on OCI sends alerts, password resets or reports through OCI Email Delivery, and some or all messages never arrive. The app may log an SMTP error, or it may report success while the recipient sees nothing.

Every message goes through two stages, and you need to know which one failed:

  1. Submission. Your app connects to the Email Delivery endpoint, authenticates and hands over the message. Failures here return an SMTP or HTTP error to the app.
  2. Relay. Email Delivery passes the message to the recipient's mail server. Failures here (bounces, complaints, suppression) are not returned to your app. You only see them in the Email Delivery logs.
export TENANCY=<tenancy-ocid>
export C=<compartment-ocid-of-the-approved-sender>

Quick map: error to cause

What you see Stage Cause Fix
535 Authentication credentials invalid Submission Wrong SMTP username or password, or the credential was deleted Create a new SMTP credential and update the app
535 Authorization failed: address <x> not authorized Submission From address isn't an approved sender, the sender is in a compartment the user's policy doesn't cover, or the user isn't in the group Add the approved sender and check the email-family policy
421 Too many auth failures, try again later Submission IP throttled after repeated bad credentials or an unapproved sender Fix the credential or sender, then wait before retrying
455 Maximum messages sent per minute/day reached Submission Send rate or daily limit hit Slow the sender or request a limit increase
552 Exceeds byte limit Submission Message too large Shrink attachments, or send a link instead
254 4.7.1 Suppression for user ... to <recipient> Submission (accepted, not sent) Recipient is on the suppression list Find out why, then remove the suppression
Connection timeout Network Port blocked, wrong endpoint or region Test the endpoint, use 587
App reports success, nothing arrives Relay Bounce, spam filtering, missing DKIM/SPF Check the outboundrelayed log

1. Check connectivity and the endpoint

The SMTP endpoint is regional: smtp.email.<region>.oci.oraclecloud.com. Your app must use the endpoint for the region where the approved sender lives. Confirm it for your tenancy:

oci email configuration get-email --compartment-id $TENANCY

Email Delivery accepts ports 25 and 587 (STARTTLS) and 465 (implicit TLS), and requires TLS 1.2. Use 587. Outbound port 25 is often blocked from cloud networks.

Test from the instance or pod that sends the mail:

openssl s_client -starttls smtp -crlf -quiet \
  -connect smtp.email.eu-frankfurt-1.oci.oraclecloud.com:587

You should see a 250 EHLO response. If the connection hangs, check the route table and NSG or security list egress for TCP 587. Private subnets need a NAT gateway, because the endpoint is public.

2. Fix authentication: SMTP credentials

SMTP credentials are separate from the console password, API keys and auth tokens. The password is shown once, when you create the credential.

oci iam smtp-credential list --user-id <user-ocid>
oci iam smtp-credential create --user-id <user-ocid> --description "app-prod smtp 2026-10"

Use a dedicated service user for each application, not a person's account. When someone leaves and their user is deleted, every app using their credential stops sending mail.

Test the new credential outside the app with Python:

import smtplib, ssl
from email.message import EmailMessage

msg = EmailMessage()
msg["From"] = "alerts@ops.example.com"     # must be an approved sender
msg["To"] = "oncall@example.com"
msg["Subject"] = "OCI Email Delivery test"
msg.set_content("Test from the app host.")

with smtplib.SMTP("smtp.email.eu-frankfurt-1.oci.oraclecloud.com", 587, timeout=20) as s:
    s.starttls(context=ssl.create_default_context())
    s.login("<smtp-username>", "<smtp-password>")
    s.send_message(msg)
print("accepted")

If this works and the app doesn't, the problem is in the app configuration: wrong host, port, TLS mode or a stale password.

3. Fix authorization: approved senders and policy

The From address must be an approved sender, and the envelope sender (MAIL FROM) should be the same address. Mismatches cause 535 Authorization failed or hurt deliverability.

oci email sender list --compartment-id $C --email-address alerts@ops.example.com
oci email sender create --compartment-id $C --email-address alerts@ops.example.com

Check that the SMTP user's group can use Email Delivery in that compartment:

Allow group app-mail-senders to use email-family in compartment ops-prod

Tip

If the approved sender sits in a different compartment from the one the policy covers, you get the same 535 not authorized error as a missing sender. Check both.

4. Find out what happened after submission

Turn on the Email Delivery logs before you need them. They're enabled per email domain, with two categories:

  • outboundaccepted: submission results, including Authorization failure, Recipient suppressed, rate limits and parse errors.
  • outboundrelayed: delivery results, with data.action set to relay, bounce, complaint or unsubscribe.

Console: Developer Services → Email Delivery → Email Domains → your domain → Logs → Enable log.

Search for bounces to a recipient over the last day:

oci logging-search search-logs \
  --search-query "search \"$C/<log-group-ocid>/<relayed-log-ocid>\" | where data.recipient = 'oncall@example.com' | sort by datetime desc" \
  --time-start "$(date -u -d '-24 hours' +%FT%TZ)" --time-end "$(date -u +%FT%TZ)"

Useful fields: data.action, data.errorType (hard or soft), data.bounceCategory, data.smtpStatus (the remote server's reply), data.dkimSelector and data.messageId.

Relay result Meaning Action
relay with 250 status Recipient's server accepted it Ask the recipient to check spam and quarantine. Check DKIM and SPF
bounce, hard, bad-mailbox Address doesn't exist Fix the address. It is now suppressed
bounce, soft Mailbox full, greylisting, temporary block Usually retried. Watch for repeats
bounce, spam-related Recipient's server rejected the content or reputation Fix DKIM/SPF, review the content
complaint Recipient marked it as spam Address is suppressed. Don't remove without consent

5. Clear a suppression

A hard bounce or complaint adds the address to the tenancy's suppression list. Suppressions are listed at tenancy level:

oci email suppression list --compartment-id $TENANCY --email-address oncall@example.com
oci email suppression delete --suppression-id <suppression-ocid>

Warning

Only remove a suppression after you've fixed the cause, such as a mistyped address or a mailbox that has since been created. If you keep sending to bouncing or complaining addresses, sender reputation drops and mail to everyone else starts landing in spam.

6. Improve deliverability: DKIM and SPF

Mail without DKIM is far more likely to be filtered. Check the DKIM state on the email domain:

oci email domain list --compartment-id $C --output table
oci email dkim list --email-domain-id <email-domain-ocid> --output table

A DKIM key in NEEDS_ATTENTION usually means the CNAME <selector>._domainkey.<email-domain> is missing or was created at the wrong name. Some DNS providers append the zone automatically, which produces ...example.com.example.com. Enter the zone-relative name instead.

For SPF, copy the include value from the console (Approved senders → View SPF) into the domain's TXT record. The value depends on the region, so don't copy it from another tenancy.

Prevent it next time

  • Enable both Email Delivery log categories on every email domain, and alarm on bounce and complaint spikes.
  • Use one service user per application, store its SMTP password in OCI Vault, and rotate it on a schedule.
  • Configure DKIM and SPF before go-live, and set the envelope sender to the same address as From.
  • Check your send rate and daily limits against peak volume. Check the current limits in the Email Delivery documentation rather than assuming them.
  • Send critical alerts through a second channel (OCI Notifications to PagerDuty or Slack), so a mail problem doesn't hide an outage.