Troubleshooting

SPF / DKIM / DMARC failures

These three protocols cooperate to prove your email is legitimate. Any one of them failing = mail goes to spam, gets dropped, or triggers a bounce with a 5.7.x code. Here's how to diagnose + fix each.

Quick triage

Open your bounce: the diagnostic-code tells you which layer failed. SendBolt classifies these into the policy_block and auth_failure categories (see bounces). Common codes:

CodeWhat failedWhere to look
5.7.1SPF or DMARCDNS records — see SPF section below
5.7.7DMARC alignmentCheck `From:` header matches DKIM `d=` AND SPF return-path
5.7.20DKIM signature missing or invalidDKIM private key issue — re-run rotation
5.7.25No PTR for sending IPReverse DNS not set
5.7.26SPF authorized IP but DMARC misalignedFrom-domain doesn't match SPF sender

SPF failures

Symptom: 5.7.1 "SPF did not pass" from Gmail

Your DNS SPF record doesn't list the IP that's actually sending.

Diagnose

# 1. What's your current SPF?
dig +short TXT acme.com | grep spf
# v=spf1 a mx include:_spf.google.com ~all

# 2. What IP is SendBolt actually sending from?
# Check your envelope-from path in the bounce email's headers:
# Return-Path: <bounces@acme.com>
# Received-SPF: fail (google.com: domain of bounces@acme.com does not designate 135.148.35.116 as permitted sender)

Common causes

  • Your SPF uses a mechanism but the a resolves to CloudFront / your web host's IPs, not SendBolt's. The a mechanism is rarely what you want — replace with ip4: or include: explicitly
  • You hit the 10-DNS-lookup limit. SPF's spec caps lookups at 10; if your record has include:_spf.google.com include:sendgrid.net include:mailchimp.com and others, you exceed it and ALL the mechanisms get ignored. Consolidate to ip4: ranges
  • You're sending via IPv6 with no SPF coverage. If your tenant has SPF for IPv4 but not IPv6, IPv6-routed mail fails. Add ip6: or force tcp4 outbound (SendBolt does this by default since W121-A)

Fix

Replace your SPF with one that explicitly lists SendBolt:

v=spf1 ip4:135.148.35.116 ip6:2604:2dc0:103:7400::/64 ~all

Or if you also send via other ESPs, include them with include: but consolidate to stay under the 10-lookup cap.

DKIM failures

Symptom: 5.7.20 / 5.7.26 "DKIM signature missing" or "DKIM=neutral"

Diagnose

  1. Check that SendBolt is signing — look at /dashboard/domains. Your domain should show DKIM "published" status
  2. From the command line:
# 1. What selector is SendBolt using?
# Find this on the domain detail page — typically mp{timestamp}, e.g. "mp1778609595"

# 2. Is the public key published?
dig +short TXT mp1778609595._domainkey.acme.com
# v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...

# 3. If empty, you didn't publish (or published wrong) the DKIM TXT record. Re-paste from /dashboard/domains.

# 4. Send a test mail to a tool like https://www.mail-tester.com or send a probe to your own Gmail and check headers:
# Authentication-Results: mx.google.com;
#   dkim=pass header.i=@acme.com header.s=mp1778609595 header.b=...

Common causes

  • You published the WRONG DKIM record — usually because you copied a selector from one tenant's docs into another tenant's DNS. The selector + key must come from the specific domain you're sending FROM
  • You published it to the wrong name — must be mp{selector}._domainkey.YOURDOMAIN.com, not mp{selector}.YOURDOMAIN.com (without the _domainkey sublabel)
  • The TXT record is too long for your DNS provider's UI — DKIM keys are 2048-bit (~400 chars). Some providers (notably older registrars) silently truncate. Switch to Cloudflare or Route53 if needed
  • The key got rotated by SendBolt's W131-G auto-rotator but you missed the email and didn't update your DNS. Both old + new selectors get a 7-day overlap, then the old one stops working

DMARC failures

Symptom: 5.7.7 "DMARC alignment failed"

DMARC requires the From: domain (visible to the user) to ALIGN with at least one of:

  • The DKIM d= domain
  • The SPF return-path domain (envelope-from)

Common cause: cross-tenant mail with the wrong DKIM key

Before W123-A shipped, SendBolt signed every tenant's mail with ONE global key (d=rahstack.dev). When a Calorisync send went out, the From was calorisync.com but DKIM was d=rahstack.dev — alignment FAIL → DMARC FAIL → mail silently dropped by strict receivers.

Since W123-A, every tenant has its own DKIM key. If you're still seeing DMARC alignment errors:

  1. Check the headers — what does the d= in DKIM-Signature say?
  2. If it says rahstack.dev instead of your domain, your tenant's DKIM keypair wasn't loaded. File a Slack issue in #sendbolt
  3. If it says your domain but DMARC still fails, check your DMARC record syntax

DMARC policy progression

If you're NEW to DMARC, start permissive and tighten:

  • Week 1-2: v=DMARC1; p=none; rua=mailto:dmarc-rua@acme.com (monitor only)
  • Week 3-4: v=DMARC1; p=quarantine; pct=25 (25% of failures → spam folder)
  • Week 5-8: p=quarantine; pct=100
  • Week 9+: p=reject if no failures in your rua reports

PTR (reverse DNS) failures

Symptom: 5.7.25 "No PTR / sending IP has no PTR"

Gmail and Outlook require reverse-DNS for the sending IP. If you're on a shared SendBolt pool, this is handled. If you're on a dedicated IP (W133-A), the IP's reverse-DNS must point to a hostname your domain's SPF/HELO can match.

This is one of the most common reasons we force tcp4 outbound by default (W121-A) — the IPv4 address has a PTR; the IPv6 doesn't.

Run the full diagnostic

mail-tester.com gives you a one-shot diagnostic across all three plus more:

  1. Get a unique address from https://www.mail-tester.com
  2. Send a real production email to it from your app
  3. Click "Check your score" — you should be 9-10/10
  4. If less, the report calls out exactly which check failed and how to fix

Still stuck?

Open /dashboard/admin/observability — the open-alerts panel surfaces DNS drift, DKIM publish failures, and bounce-rate spikes. If everything reads green there but Gmail still rejects, ping the founder via #sendbolt Slack with the bounce headers attached.