The contact form defaulted to sending from noreply@fiferouter.com.
The verified sender in the Postmark account was noreply@mail.fiferouter.com — the
sending subdomain. Every message would have been rejected with a 300-series
error code, on every attempt, forever.
Caught before it shipped by asking rather than assuming, which is the only reason this is a short post.
Why it would have looked like something else
The handler is written to survive a bad afternoon at the mail provider:
if res.status_code != 200:
logger.error("contact: Postmark refused (http %s, ErrorCode %s)", ...)
return JSONResponse({"error": "send_failed", ...}, status_code=502)
A 502 and a "could not send that just now, please try again" is the right
response to a transient outage. It is the wrong response to a permanent
misconfiguration, and it is indistinguishable from one.
So the symptom would have been: contact form broken, retries do not help,
nothing obviously wrong in the application, and a 502 that says try again to
somebody for whom trying again will never work.
The ErrorCode in that log line is what would have shortened the search — a
300-series code means the sender is not verified, and it is the difference
between "Postmark is having a bad minute" and "you configured this wrong". Which
is why it is logged and why the response body is not: the body echoes the
visitor's message back, and a log is not the place for somebody's text.
The subdomain is the right answer anyway
The correction was one default, and the arrangement it moved to is the one you would want regardless.
DKIM keys and the Return-Path live on the sending subdomain, so transactional
reputation is separable from the apex. If the contact form has a bad week —
somebody scripts it, a provider decides the volume looks odd — mail.fiferouter.com
absorbs it and fiferouter.com does not.
Sending from the apex ties your marketing domain's reputation to your most abusable endpoint. The subdomain costs one DNS record and buys a blast radius.
The thing to check that is not the From address
A verified sender signature will send. That is not the same as arriving.
Unauthenticated mail — no DKIM, no SPF alignment, no Return-Path on your domain
— reaches Gmail and Outlook often enough to look like it works and lands in spam
often enough that you conclude the form is broken. The failure is worse than a
rejection because it is silent on both ends: your side reports 200, and the
recipient never sees it.
So the check is not "did Postmark accept it" but "does the domain show DKIM verified and a Return-Path record". Which is a DNS job, and belongs on the checklist beside the A records rather than in the application.
What we changed about the habit
The form was built, tested and reviewed against a From address nobody had
confirmed existed. Every test passed, because the tests assert what we send —
that the visitor goes in ReplyTo and never From, that headers cannot be
injected, that the recipient is configuration — and none of them can know
whether Postmark will accept the envelope.
The gap is that "is this address verified with the provider" is not a fact the repository contains. It lives in someone else's dashboard, and the only two ways to know are to ask or to send.
We asked. The cheaper habit would have been to send one test message the moment the token existed, before building anything on top of it — the same reasoning as seeing a monitor pass green before counting it as shipped.