Actions
Troubleshooting
Common failure modes, organised by what shows up in the invocations table.
Where to look first
- Dashboard Actions → [your action] → Recent invocations. Every call is logged with status, duration, HTTP status, and an error string. The list is capped at 100 by default.
- Click details on a failing row to see the response-body SHA-256 + the full error message.
- Use Send test event to fire a synthetic event on demand. Easier than trying to reproduce by signing in.
The synthetic test event carries metadata.test === true. Your webhook can short-circuit when it sees that and return { "decision": "allow" } without touching the rest of your logic — useful for testing connectivity without mutating your data.
By invocation status
status = network_error
- DNS resolution failed. Check that your domain’s A/AAAA records are public.
- Connection refused / reset. Your endpoint is down, or a firewall is dropping Authio’s outbound IP (Authio egresses from the auth-core deploy’s region).
- TLS handshake failure. Expired cert, self-signed cert, or TLS < 1.2. Authio enforces a public CA chain and TLS 1.2+; we do NOT support pinning a custom root on the customer side.
status = ssrf_blocked
Your endpoint URL resolves to a blocked IP range (RFC 1918, link-local, loopback, multicast, AWS metadata169.254.169.254, ULA, NAT64) OR matches an Authio-owned suffix. Re-check the URL — typos in subdomains sometimes resolve to an internal range via wildcards.
status = timeout
- Your endpoint took longer than the configured
timeout_msto respond. Lambda cold-starts are the most common cause — give the function provisioned concurrency, or bump the timeout to 5000 ms (the max). - A persistent timeout rate > 50% over 5 minutes will trip the kill-switch.
status = http_error
Your endpoint returned a non-2xx HTTP status. The http_status column shows the exact code. Most likely:
- 401: Your signature-verification code is rejecting Authio’s request. Confirm
AUTHIO_ACTION_SECRETmatches the value you copied on create — and that you’re using the raw body, not a re-stringified parsed JSON (those differ in whitespace). - 500: Bug in your handler. Check your logs.
- 503: Your endpoint is overloaded. 100 consecutive 5xx responses trip the kill-switch immediately.
status = invalid_response
- The response body was not valid JSON.
- The response body was > 64 KiB. Cap your response size — you don’t need to echo the event back, just the verdict.
- The response carried a malformed
Authio-Response-Signatureheader.
status = invalid_signature
Authio asked for a response-signature verification (you set the Authio-Response-Signature header) and the signature failed to validate. Three causes:
- Wrong secret. The signing secret on your side doesn’t match the one Authio has. Rotate it from the dashboard.
- Body changed after signing. Don’t add a trailing newline, don’t pretty-print after signing.
- Timestamp skew. Authio rejects response signatures whose
t=is more than ±5 minutes from its own clock. NTP your machine.
status = rejected
Not a failure — the customer’s webhook returned decision: deny. The deny_code / deny_reason surface in the invocation row’s details.
status = killed
The action was killed by the auto kill-switch before this invocation could be attempted. See Kill-switch behavior.
Pattern 3 — "my JWT still shows Authio roles"
- Is
roles_action_overrideon for the project? Without it, youroverride_rolesfield is dropped. Check Settings → Authorization. - Look at the action’s invocation row — does it carry the
overridepill? - If yes but the JWT still shows Authio roles, every override slug was unknown to the project’s
rolestable. Look foraction.override_unknown_roles_droppedin the audit log; the metadata shows which slugs were dropped. Create matching role rows via the dashboard orPOST /v1/session/roles.
"My endpoint receives the call but Authio never sees the response"
- Confirm your response is < 64 KiB.
- Confirm your response uses
Content-Type: application/jsonand is valid UTF-8. - Confirm you’re not returning a 3xx — Authio refuses ALL redirects on action calls at the HTTP-client layer.
"Authio called my endpoint with a different secret than I configured"
The secret you see in the dashboard is sha256(raw_secret). Authio holds the raw secret in memory only — after an auth-core restart, the raw is gone until you rotate. If your invocations suddenly start coming with a signature that doesn’t match, rotate from the dashboard and update your env var.
Get help
If none of the above resolves it, file a support ticket with:
- Your action ID (
action_…from the URL). - An invocation ID from the Recent invocations table.
- Your endpoint’s logs for the same timestamp.
