TLDR: If you manage SendGrid DNS records in Cloudflare, make sure PTR-related records are set to DNS-only. Proxying them silently breaks reverse DNS verification and causes email delivery failures with no alerts or warnings.
The setup Link to heading
If you use SendGrid with a dedicated IP, you’ll have a PTR record so receiving mail servers can verify your identity through reverse DNS.
The way this works: when a mail server receives a connection from your IP, it does a reverse lookup (dig -x <your-ip>) to get a hostname, then a forward lookup on that hostname to check the IP matches. This is called FCrDNS — forward-confirmed reverse DNS. If it doesn’t match, the server assumes you’re suspicious and rejects or defers your email.
The PTR record points to a hostname like o1.ptr1234.example.com, which has an A record pointing back to the SendGrid IP. Simple enough.
The one-character change Link to heading
The problem starts when someone toggles the PTR hostname’s A record from DNS-only (grey cloud) to proxied (orange cloud) in Cloudflare. In Terraform terms:
# correct
resource "cloudflare_record" "sendgrid_ptr" {
name = "o1.ptr1234"
type = "A"
content = "159.x.x.x"
proxied = false # DNS-only — returns the actual IP
}
# broken
resource "cloudflare_record" "sendgrid_ptr" {
name = "o1.ptr1234"
type = "A"
content = "159.x.x.x"
proxied = true # proxied — returns a Cloudflare IP instead
}
With proxying enabled, the forward lookup on the PTR hostname returns a Cloudflare edge IP (something like 104.x.x.x) instead of the actual SendGrid IP (159.x.x.x). The reverse and forward lookups no longer match. FCrDNS is broken.
No alerts fire. No monitoring catches it. SendGrid’s dashboard shows increasing deferrals, but deferrals happen for lots of reasons — it’s easy to miss.
What the errors look like Link to heading
The most common error in SendGrid’s activity feed is:
450 4.7.25 Client host rejected: cannot find your hostname, [159.x.x.x]
That 450 is a temporary failure — the receiving server is saying “I can’t verify who you are, try again later.” SendGrid retries these for up to 72 hours, but with the DNS misconfiguration persisting, retries keep failing too. After 72 hours, the deferral becomes a permanent bounce.
The fix is reverting proxied = true back to proxied = false. But once you’ve fixed it, you need to figure out the blast radius — and that’s where the error messages get confusing.
Sorting through the wreckage Link to heading
If you query your email event logs after something like this, you’ll see a mix of errors. They fall into two very different buckets, and the distinction is not obvious.
Errors caused by the misconfiguration Link to heading
450 4.7.25 Client host rejected: cannot find your hostname, [159.x.x.x]
The tell is your sending IP appearing in the error. The receiving server is literally saying “I looked up your IP and couldn’t find a matching hostname.” That’s the broken FCrDNS.
Errors that look related but aren’t Link to heading
Once you’re investigating a PTR issue, every failure looks like it might be connected. These aren’t.
The phantom PTR
unable to get mx info: failed to get IPs from PTR record: lookup <nil>
This one is the most misleading. It mentions “PTR record” right there in the error — so during a PTR investigation, it looks like your problem.
It’s not. Despite the wording, this error means SendGrid couldn’t resolve the recipient’s domain. The <nil> is a null DNS response — the recipient’s domain has no MX records, no fallback A record, nothing. SendGrid can’t figure out where to deliver the email.
You can confirm by running dig MX against the affected domains. They’ll return empty — expired domains, misspelled company names, small businesses with broken DNS. Nothing to do with your PTR record.
The connection timeout
dial tcp 192.0.2.1:25: i/o timeout
SendGrid opened a TCP connection to the recipient’s mail server and it didn’t respond. The server is down, firewalled, or overloaded. Note the IP in the error is the recipient’s mail server, not yours.
The TLS failure
remote error: tls: handshake failure
SendGrid connected to the recipient’s server but the TLS negotiation failed — usually an expired certificate or misconfigured TLS on the receiving end.
The rate limit
421 4.7.28 [...] Our system has detected an unusual rate of unsolicited mail originating from your IP address.
This one can be related to a PTR issue — poor FCrDNS contributes to bad sender reputation, which makes rate limiting more aggressive. But it’s not a direct consequence of the misconfiguration. It’s the receiving server (usually Gmail) throttling you, and it resolves on its own once your PTR is fixed and reputation recovers.
The key rule Link to heading
If the error contains your sending IP and mentions hostname verification, it’s your problem. Everything else — <nil>, timeouts, TLS failures, recipient server errors — is probably not.
The Cloudflare gotcha Link to heading
The underlying lesson is about Cloudflare’s proxy mode and email infrastructure. Cloudflare proxying is great for web traffic — it hides your origin IP, provides DDoS protection, and caches content. But for DNS records that exist purely for email authentication, proxying is catastrophic.
Records you should never proxy in Cloudflare:
- PTR hostname A records — must return the actual IP for FCrDNS
- SPF-related records — must resolve to actual mail server IPs
- MX records — Cloudflare doesn’t proxy email traffic anyway, but the A records they point to must be DNS-only
The dangerous thing is that Cloudflare won’t warn you. Toggling the proxy on an email-related record is silent. There’s no “hey, this looks like an email authentication record, are you sure?” prompt. It just starts returning the wrong IP.
If you manage DNS in Terraform, I’d recommend adding a comment on every email-related record:
resource "cloudflare_record" "sendgrid_ptr" {
name = "o1.ptr1234"
type = "A"
content = "159.x.x.x"
proxied = false # MUST be false — email PTR record, proxying breaks FCrDNS
}
Verifying your PTR setup Link to heading
A quick way to check your PTR setup is healthy:
# Get the PTR hostname for your IP
dig -x 159.x.x.x +short
# → o1.ptr1234.example.com
# Verify forward lookup matches
dig o1.ptr1234.example.com +short
# → 159.x.x.x (must match the original IP)
If the second command returns a different IP (especially one in Cloudflare’s ranges like 104.x.x.x or 172.x.x.x), your record is being proxied.
It’s worth setting up monitoring for this. A simple cron job that does the two dig commands above and alerts if they don’t match would catch this immediately. Email delivery fails silently — nobody complains about the invoice they never received, they just don’t pay it.
Further reading Link to heading
- How to set up reverse DNS — SendGrid’s guide to PTR record setup
- Bounce and block classifications — SendGrid’s taxonomy for delivery failures
- Event webhook reference — all SendGrid event types and fields
- Proxied DNS records — Cloudflare docs on what proxying actually does