Skip to content

Auth0 cannot send email through SendGrid โ€” 451 Authentication failed: Could not authenticate

Date resolved: 2026-07-30 Tenant: attracs / prod-eu-1 Impact: All Auth0 outbound notification email (verification, password reset, invitations, provider test mails) failed. No mail left the tenant while the condition lasted. Verdict: Not a credential problem. SendGrid IP Access Management was blocking Auth0's outbound mail servers. Fixed by allowlisting Auth0's EU backend IP addresses in SendGrid.


1. The alert

Auth0 tenant logs, repeating on every send attempt:

{
  "date": "2026-07-30T09:59:43.659Z",
  "type": "fn",
  "description": "To: billing_account@aholadigital.com",
  "connection_id": "",
  "ip": "212.226.141.42",
  "details": {
    "email_type": "try_provider_configuration_email",
    "notification_type": "try_provider_configuration_email",
    "to": "billing_account@aholadigital.com",
    "error": "Error sending email: Invalid login: 451 Authentication failed: Could not authenticate"
  },
  "user_id": "",
  "user_name": "billing_account@aholadigital.com",
  "environment_name": "prod-eu-1",
  "log_id": "90020260730095943682952000000000000001223372172420943195",
  "tenant_name": "attracs",
  "isMobile": false,
  "user_agent": "Other 0.0.0 / Other 0.0.0",
  "location_info": {}
}

How to read this entry:

Field Meaning
type: "fn" Auth0 log code for Failed Sending Notification โ€” Auth0 accepted the job and failed at the SMTP hop. Nothing wrong upstream of the mail provider.
email_type: try_provider_configuration_email This particular event is the "Send test email" button in Branding โ†’ Email Provider. Useful: it means we had a one-click reproducer and did not need to wait for a real user signup to test.
Invalid login: โ€ฆ Invalid login is the nodemailer wrapper text, not SendGrid's. The provider's actual answer is only the part after it. This prefix is what pushed us toward the credentials theory.
451 โ€ฆCould not authenticate SendGrid's real answer. See ยง3.
ip: 212.226.141.42 Trap. This is the browser IP of the operator who triggered the send โ€” not the host that talked to smtp.sendgrid.net. Allowlisting it would have changed nothing.

2. First hypothesis โ€” expired / revoked API key (wrong)

The reasoning was sound on its face: an authentication failure against SendGrid, and the account uses an API key as the SMTP password (username = apikey, password = <SG.xxxx>). Keys get revoked, rotated by someone else, or truncated on paste.

Action taken: created a new SendGrid API key and set it in the Auth0 email provider config.

Result: identical 451 Authentication failed: Could not authenticate.

That negative result was the most valuable thing we produced. A brand-new key failing exactly like the old one rules out the entire credential class of causes โ€” the secret was never the variable. Two further points that argue against the original theory:

  • SendGrid API keys do not expire on a timer. They stop working only if revoked, deleted, or scope-restricted. "It probably expired" was never a real mechanism.
  • Bad credentials on SendGrid's relay normally come back as 535 Authentication failed: Bad username / password. We were getting 451, which is a different class of answer (see below).

Cost of this step: it introduced a second variable mid-incident. If the allowlist fix had landed at the same time as the key swap, we would not have known which change fixed it. Change one thing at a time.


3. The pivot โ€” reading the status code instead of the message text

451 is a transient SMTP class (4xx = try again later), whereas genuine credential rejection is permanent (535). SendGrid returning "could not authenticate" transiently is the tell: the relay is refusing to even begin authenticating the session, rather than evaluating a secret and rejecting it.

SendGrid's own support documentation is explicit about this and names a single cause:

This is a common issue that always points to an issue with IP Access Management (IPAM), a security feature that only allows a specific IP to access the account. SMTP users sending via IPs that are not on the Allow List will see an SMTP response of 451 Authentication failed: Could not authenticate.

IP Access Management gates all three SendGrid surfaces โ€” web UI, API, and SMTP relay. Once any IP is on that list, everything not on the list is blocked. This is the piece that made the incident hard: the feature is configured in the SendGrid account, but the failure surfaces in Auth0's logs as an authentication error, so every instinct points at the secret rather than at the network policy.

Root cause: IP Access Management was active on the SendGrid account, and Auth0's outbound mail infrastructure was not on the allow list. Auth0 does not send from the tenant's own IP or from a stable single address โ€” it sends from a documented pool of regional backend IPs, none of which had ever been added.


4. The fix

Added Auth0's EU backend IP address list to SendGrid โ†’ Settings โ†’ IP Access Management on 2026-07-30.

18.197.9.11
18.198.229.148
3.125.185.137
3.65.249.224
3.67.233.131
3.68.125.137
3.72.27.152
3.74.90.247
34.246.118.27
35.157.198.116
35.157.221.52
52.17.111.199
52.19.3.147
52.208.95.174
52.210.121.45
52.210.122.50
52.28.184.187
52.30.153.34
52.57.230.214
54.228.204.106
54.228.86.224
54.73.137.216
54.75.208.179
54.76.184.103

24 addresses. They split cleanly into two AWS regions, which matters operationally:

Group Addresses Consistent with
Frankfurt 3.125.185.137, 3.65.249.224, 3.67.233.131, 3.68.125.137, 3.72.27.152, 3.74.90.247, 18.197.9.11, 18.198.229.148, 35.157.198.116, 35.157.221.52, 52.28.184.187, 52.57.230.214 eu-central-1
Ireland 34.246.118.27, 52.17.111.199, 52.19.3.147, 52.30.153.34, 52.208.95.174, 52.210.121.45, 52.210.122.50, 54.73.137.216, 54.75.208.179, 54.76.184.103, 54.228.86.224, 54.228.204.106 eu-west-1

The Auth0 EU region spans both regions, so a partial allowlist produces intermittent failures โ€” some sends succeed, some get 451, depending on which backend picks up the job. Anything less than the full list is a worse bug than the total outage we had, because it looks like a flaky provider. Add the whole list or none of it.

Verification: Branding โ†’ Email Provider โ†’ Send test email now delivers, and no further type: "fn" entries appear in the tenant log.


5. Why this took a while

Worth recording, because the same shape will recur:

  1. The error message named the wrong subsystem. "Authentication failed" is a credentials word. The actual fault was a network ACL. Every layer in the chain โ€” nodemailer's Invalid login, SendGrid's Could not authenticate โ€” reinforced the wrong theory.
  2. The status code carried the real signal and it was the easiest thing to skim past. 451 vs 535 was the whole answer, sitting in the log from the first occurrence.
  3. The ip field in the Auth0 log is a decoy. It is the actor, not the sender. In an IP-allowlist incident, having a wrong-but-plausible IP right there in the payload is actively misleading.
  4. The broken config lives in a different console than the error. Nothing in Auth0 can show you SendGrid's IPAM state. Cross-vendor causes are invisible from the side that reports the symptom.
  5. The trigger is silent and may not be ours. IPAM can be switched on by any account admin, or as part of a security hardening pass, and produces no notification on the Auth0 side. There is no "config changed" event to correlate against โ€” worth checking SendGrid's account activity log to establish when the list was enabled and by whom.

6. Follow-ups

  • [ ] Confirm which API key is live. A second key was created during triage. Verify what Auth0 currently holds, then revoke the unused one so there is exactly one valid credential.
  • [ ] Keep our own admin access allowlisted. IPAM also gates the SendGrid UI and API. If the office egress IP ever changes and is not on the list, we lock ourselves out of the console we need to fix it. SendGrid support has to unlock that.
  • [ ] Audit the rest of the account for the same blast radius. Any other service authenticating to this SendGrid account โ€” application transactional mail, monitoring alerts, CI โ€” is subject to the same list. If those still work, their IPs are already on it; if any are broken, this is why.
  • [ ] Treat the IP list as perishable. Auth0 publishes these per region and states they can change. Re-check the published list periodically and after any Auth0 region or tenant migration, and re-verify with the test-email button.
  • [ ] Consider whether IPAM is the right control here. Its value against a stolen API key is real, but it is fragile against providers that send from rotating cloud IPs. An alternative is to drop the SMTP relay in favour of scope-restricted API keys and accept IP-independence, or to keep IPAM but document the list as an owned artifact with a review date.
  • [ ] Alert on it. type: "fn" in the Auth0 tenant log means users are silently not receiving password resets. This should page someone rather than be discovered by a person clicking a test button.

7. Runbook โ€” Auth0 email suddenly stops working

  1. Reproduce with Branding โ†’ Email Provider โ†’ Send test email. Cheap and immediate.
  2. Read the numeric SMTP code in the tenant log, not the prose:
  3. 451 Authentication failed: Could not authenticate โ†’ IP allowlist, not credentials. Go to SendGrid IP Access Management.
  4. 535 Authentication failed: Bad username / password โ†’ genuine credential problem. Check the key and that the SMTP username is literally apikey.
  5. 550 The from address does not match a verified Sender Identity โ†’ sender verification / domain authentication, not auth at all.
  6. Ignore the ip field in the log entry. It is the operator, not the sender.
  7. Change one variable per test, and re-run the test email between changes.

Sources