KoltrixKoltrix docs

Troubleshooting

A growing list of the most common gotchas, with the actual fix — not just "check your config." Each entry tells you what you'd see, why it happens, and exactly what to do.

Email isn't being delivered

You sent a transactional email and the recipient never got it. Walk through this in order:

  1. Check Settings → Email logs. Every send shows up here with a status:
    • queued for more than 30 seconds → contact support; the queue is normally drained within a second.
    • sent but never delivered → the receiver didn't return a DSN. Most likely the message arrived fine; check the recipient's spam folder first.
    • bounced → the SMTP reply column tells you why. Usually a typo'd address or a 550 from the receiver.
  2. Verify your domain DNS records are all green under Settings → Domains → <domain>. Especially DKIM — without a valid DKIM signature most inboxes spam-bin you on principle.
  3. Run mail-tester.com against an address on your domain. Aim for 9–10/10. Anything under 8 points at a misconfiguration the tool will name.
  4. New domain? Check Settings → Warmup. You may be capped at a small daily quota for the first week — sends past the quota are paused until the counter resets.

"from address … is not registered for this account" (HTTP 403)

The API rejects from: addresses that aren't an active mailbox on a verified domain — even if the domain itself is verified, an unknown local-part will fail. The fix:

  1. Open Settings → Domains → <your domain>.
  2. Click Add address and add the exact mailbox you want to send from (e.g. [email protected]).
  3. Retry the API call. The error message tells you which case failed (domain unverified vs domain verified but address missing) so you know exactly what to fix.

"rate limit exceeded" (HTTP 429)

You hit the per-IP (300/min) or per-key (60/min) sliding-window limit. Back off with exponential retry — treat 429 as "wait 5s and try again, double the wait on repeated 429s." If you legitimately need higher throughput, email [email protected] — we raise it on the account for real workloads.

Sequences and broadcasts share the per-account warmup budget, not the per-key quota — so a hot send loop won't lock out your transactional traffic.

"invalid or revoked api key" (HTTP 401)

  • Did you copy the full key including the kx_ prefix?
  • Did someone revoke it in Settings → API Keys? Revoked keys return 401 immediately, even if they were valid two seconds ago.
  • Check the request shape: Authorization: Bearer kx_... — note the space and the Bearer prefix.

"missing permission: …" (HTTP 403)

The key is valid but doesn't include the scope this endpoint needs. Open Settings → API Keys and either:

  • Mint a new key with the right scope (send, newsletter, read, contacts, or *), deploy it, then revoke the old one.
  • Or, if the original key was over-scoped intentionally, double-check which scopes were ticked at creation — scopes are immutable after the fact.

Rotating a key

There's no in-place rotation. The pattern:

  1. Mint a new key in Settings → API Keys with the same scopes as the old one.
  2. Deploy the new key everywhere the old one was used.
  3. Revoke the old key. Revocation takes effect immediately; in-flight requests finish without interruption.

Domain won't verify

If Settings → Domains → <domain> → Verify keeps failing:

  • Wait. DNS propagation can take a few minutes to a few hours depending on your registrar and TTL. Re-check every 60 seconds.
  • Compare records exactly. Some registrars helpfully add quotes or trim trailing dots — paste from our values, not from a previous attempt.
  • DKIM record too long? Some DNS UIs split long TXT values awkwardly. The "value" should be the entire string we showed; if your registrar requires 255-char chunks, concatenate them with no separators when entering.
  • CNAME for DKIM? A few registrars don't allow TXT at subdomain selectors. Switch to TXT directly if a CNAME isn't being resolved.

If you've waited an hour and re-checked everything, dnschecker.org will show whether the record has actually propagated globally.

"warmup quota exceeded"

Your domain is still in its first weeks. Either wait until tomorrow (the daily counter resets at midnight server time) or pause warmup in Settings → Warmup once you trust the domain. Pausing warmup is strongly discouraged in the first week — your sender reputation has to be built first.

Webhook not arriving

  1. Check the dashboard. Settings → Webhooks → endpoint → Deliveries shows every attempt with its status code and response body.
  2. Confirm the event is subscribed. If the webhook isn't listening for that event type, no row will exist.
  3. Look at the response body. A non-2xx response from your endpoint is the most common failure. If it's 401 / 403, you're probably rejecting our signature — see the verification snippets in Webhooks.
  4. Use raw body to verify signatures. If your framework parses JSON before your handler sees it, the signature won't match. Use a raw-body middleware.

Webhook signature doesn't verify

Pretty much always one of:

  • Verifying against the parsed JSON instead of the raw bytes. Fix: use express.raw({ type: "application/json" }) (or your framework's equivalent).
  • Trimming whitespace from the body. Don't — the signature is over the exact bytes we sent.
  • Using the wrong secret. Each endpoint has its own; copy from the dashboard, store as an env var on your handler.

Bounces auto-suppress (and how to un-suppress)

A hard bounce (SMTP 5xx) adds the recipient to the suppression list with a reason. Every subsequent send — transactional, newsletter, sequence — silently skips that address.

To un-suppress (after confirming the underlying issue is fixed):

  • Dashboard: Settings → Suppressions → find address → Remove.

If the bounce happens again immediately, the address genuinely doesn't exist. Stop trying to send to it.

SMTP relay rejects MAIL FROM

501 5.5.4 Invalid FROM address

The relay parses standard MAIL FROM:<addr> with extensions. Make sure your client wraps the address in angle brackets:

MAIL FROM:<[email protected]> SIZE=571

Without the <> the parser can grab a SIZE= chunk and reject.

Sequences aren't firing

Common causes:

  • The sequence isn't active — toggling off pauses new enrollments. Toggling on doesn't backfill past triggers either.
  • The list has no from_address — sequences pause an enrollment with status paused when the list has no from-address. Set it under the list's settings and resume the enrollment.
  • The subscriber is pending — double-opt-in subscribers don't enroll until they confirm.

When all else fails

Email [email protected] with:

  • What you tried, what you expected, what actually happened.
  • The message ID from Settings → Email logs (if it's a delivery issue).
  • A timestamp (so we can find the right window in our logs).

We respond within one business day.