UTAH, USAAI + DATA + AUTOMATIONNEXT AVAILABLE: APR 7ACCEPTING NEW PROJECTSBUILT WITH NEXT.JS ON VERCELUTAH, USAAI + DATA + AUTOMATIONNEXT AVAILABLE: APR 7ACCEPTING NEW PROJECTSBUILT WITH NEXT.JS ON VERCEL
BACK TO DISPATCHES
2026-03-14·4 min read·EMAILRESENDCLOUDFLAREDEBUGGING

Why My Contact Form Emails Disappeared Into the Void


What I Built

The contact form on this site saves submissions to Supabase and sends me a notification email via Resend. Pretty standard stuff. But when I tested it after launch, the notification never showed up.

The Problem

I submitted the contact form a few times to test it. Submissions were landing in Supabase, the form was showing a success message, but no email. I checked the Resend dashboard: API key was valid, domain was verified. I even sent a test email via curl and got a success ID back. Everything said it was working. It wasn't.

The Investigation

The obvious stuff

Standard debugging checklist. API key? Valid. Domain verified in Resend? Yep. Environment variables set in Vercel? All there. Server logs? No errors.

Here's the email code in the API route:

// Send email notification (non-fatal, submission is already saved)
const contactEmail = process.env.CONTACT_EMAIL;
if (contactEmail) {
  try {
    const resend = new Resend(process.env.RESEND_API_KEY);
    await resend.emails.send({
      from: "Porter IS <notifications@porterintelligent.com>",
      to: contactEmail,
      subject: `New inquiry from ${name}`,
      text: [/* formatted fields */].filter(Boolean).join("\n"),
    });
  } catch (emailErr) {
    console.error("Resend notification failed:", emailErr);
  }
}

The non-fatal try/catch is intentional. If the email fails, the submission is already in Supabase so the user shouldn't see an error. Good for UX, not great for noticing when things break.

Problem 1: No mailbox

I was sending to mason@porterintelligent.com. Domain was verified in Resend. But Resend is a sending service. Domain verification proves you own the domain for outbound mail. It doesn't set up a mailbox for receiving.

There was nothing at that address. Emails were bouncing.

Since my DNS is already on Cloudflare, I set up Cloudflare Email Routing to forward mason@porterintelligent.com to my Gmail. Free, took a couple minutes.

Problem 2: The suppression list

Forwarding set up. Sent another test. Still nothing.

Went back to the Resend dashboard and actually looked at the email statuses:

Resend dashboard showing Suppressed, Bounced, and Delivery Delayed statuses
Delivery Delayed, Bounced, Suppressed: reading bottom to top, you can see exactly what happened.

Reading bottom to top: my first test was "Delivery Delayed" (sent before the mailbox existed). The curl test bounced (still no mailbox at that point). And then the third attempt was "Suppressed," meaning Resend saw the bounce and automatically blocked future sends to that address to protect my sender reputation.

The API was still returning success IDs for suppressed sends. No error, no exception. You have to check the dashboard to see it.

Removed the address from Resend's suppression list, sent another test, and it landed in Gmail.

The Result

The full chain works now: form submission → Supabase → Resend → Cloudflare Email Routing → Gmail. No code changes needed, the API route was fine the whole time. Both issues were infrastructure config.

What I Learned

Sending and receiving are separate problems. Verifying a domain in Resend means you can send from it. Receiving mail at that domain is a totally different thing. You need a mailbox or forwarding set up separately.

Suppression lists are sneaky. Resend will accept your API call and return a success ID even when it's suppressing delivery. Makes sense from their perspective, they're protecting your sender reputation. But it means "API returned 200" and "email was delivered" are not the same thing.

Non-fatal error handling cuts both ways. Swallowing email errors is the right call for the user-facing form, but it also means you won't notice when things stop working unless you're checking the dashboard. Worth thinking about some kind of lightweight monitoring down the road.

For now, the forwarding setup works fine. Cloudflare is beta testing full email sending support though, and I signed up for the waitlist. If I get access, I'll set up a proper mason@porterintelligent.com mailbox and write up that process too.