Troubleshooting: quiet-hours blocks that fired during allowed hours
A recipient says “the send was fine — it went out at an allowed hour,” yet your logs shownext_allowed_at and a block. That’s a false-positive
quiet-hours block: a gate that held a send while the recipient’s local
time was technically legal but the wrong layer or a DST misread said
otherwise. This page works the triage — which of three false-block
layers fired, how each layer’s responsible knob differs, and how to file
the override without weakening the one platform-owned gate. For the
three-layer model itself, see
Federal vs state vs tenant voice gates;
this page works the failures, not the statutes.
The three false-block layers
A quiet-hours block that reportsnext_allowed_at while the recipient
is in allowed hours came from one of three layers, and each layer
owns a different knob. Identifying the layer first halves the debugging
time — and decides whether you fix it yourself or escalate it.
A single send can cross more than one layer, but the layers compose
most-restrictive-wins — the first layer that blocks wins the log, and
the recipient reports “the send went out” while the platform held it
on the layer they didn’t see. For the composition rule, see
Federal vs state vs tenant voice gates.
The DST and timezone-resolution traps
Off-peak sends that still tripnext_allowed_at are almost always one
of these two traps. Both are read-path defects (the send path inherited
the wrong zone or the wrong hour), never send-path bypasses.
DST crossover
Twice a year, US daylight-saving time flips the recipient-local clock. A contact-CRM field stamped “Pacific” no longer meansUTC-8 in July —
the DST-aware evaluation resolves the IANA timezone against the
recipient’s actual local time, but naive integer-hour shortcuts in your
own scheduling layer re-derive the wrong offset. The most common DST
false positive is a send that “was scheduled for 9 AM local” by your
own worker, which crossed the spring-forward boundary and reopened the
window an hour early or an hour late. Worked timelines and the correct
pre-launch procedure are in
Quiet hours across DST — the fix
is to hand the deferral to the platform’s next_allowed_at rather
than recompute on your side.
Recipient-local timezone resolution
Thenext_allowed_at value is computed against the recipient’s
resolved local hour. When the area code resolves to the wrong zone (a
relocated number, a VOIP number that has kept its original area code,
a zone with two DST-adjacent aliases like Arizona’s Phoenix) a send
scheduled for one local hour lands at the wrong one. Run the preview
against the same recipient before you re-diagnose:
local_timezone mismatches the recipient’s true zone,
the fix is to persist the correct zone on the contact (or pass the
read-path &timezone_override=<iana-name> at preview) — never to
relax your unknown_timezone_policy. When the timezone resolution
itself is broken (an unresolved NANP area code, or a US recipient whose
area code is not yet mapped), work
Dialing-window blocked voice calls
first — resolution failures are their own class with their own
fail-closed posture.
When the federal rail is the culprit
The TCPA federal voice window is the sole platform-owned gate in the stack — the only one with no tenant toggle, noskip flag, no
fail-open posture, and 47 U.S.C. § 227(b)(1)(B) framing the penalty
as one the platform cannot let you waive. That carve-out exists to keep
you from accidentally widening the federal envelope with a misreading.
If a send was held by this rail while the recipient says “the hour was
fine,” only two outcomes are possible:
- The federal rail itself misfired — a genuine DST or resolution
defect in the rail. File it as a platform defect. Include the
full error body, the campaign or run ID, and the preview response.
Never attempt a bypass, a
skipTcpaflag, astartHour/endHourknob on the federal window, or a fail-open on an unresolvable timezone — those would reopen the exact class of incident the carve-out closed. - The federal rail read your send path wrong — a campaign pacer that deferred the contact, and your own dispatcher pushed the send straight to the gateway anyway. Work the sentinel trail on TCPA voice-guard sentinel breadcrumbs to confirm the pace-defer ran before the gateway threw; if your own scheduler bypassed the pacer’s deferral, fix the scheduler, not the guard.
Where to file each false positive
Each failure mode routes to a specific knob, a runbook to inspect, and a place to record the override. Work the table once per false-positive report, then follow the link for the deep walkthrough.
When a false positive doesn’t fit any row — the send genuinely was in
window, the timezone genuinely resolved right, and the deferral still
landed — escalate with the full error body, the campaign or run ID, and
the preview response for the same recipient. That’s the signal the
carve-out closed: a platform-only defect the sentinel can’t see, not a
setting you can change.
See also
- Federal vs state vs tenant voice gates — the three-layer model and the precedence rule; read this once before working any false positive.
- Troubleshooting: resolve dialing-window blocked
calls — when the same
next_allowed_atreports on an ad-hoc 1:1 dial, work the error codes here first; this page handles the campaign/bulk failure shapes only. - TCPA voice-guard sentinel breadcrumbs — when you need to prove the federal rail actually ran (or didn’t) on the send path, the sentinel breadcrumb trace is the audit trail.
- Quiet hours configuration — the org gate, the campaign fallback window, and the unknown-timezone policy: the two tenant-owned knobs end to end.
- Quiet hours across DST — the crossover rules, the two non-DST US zones, and the pre-launch preview procedure.
- US state calling windows — the seven-state overlay and why a state reason code layers on top of the three false-block layers above.
- Send gates — the full send-time gate stack the quiet-hours layers sit inside (DNC, RND, RMD, BAA, frequency).