Skip to main content
Every AFAuth failure returns a stable code in an error envelope. Program against the code, not the HTTP status — and find yours below.

Signature rejected (401)

Clock skew is the most common first-request failure. A signed request is valid for at most 300 seconds and tolerates ±60 s of drift between agent and service. If your agent’s clock is off — common in containers and CI — every signature reads as future-dated or expired. Sync time before debugging anything else.
replayed_nonce under load on a multi-instance service usually means a per-process nonce cache. §5.6 requires the seen-(keyid, nonce) set to be shared and atomic across every verifier instance. On Cloudflare, use DurableObjectNonceStore, not KvNonceStore, for atomic check-and-set. See Deploy to Cloudflare Workers.

Attestation rejected (401)

A common invalid_attestation cause is an aud mismatch: the agent minted for did:web:api.example.com but the service’s service_did is did:web:example.com. They must be identical.

Claim & ownership (401 / 403 / 409)

Lifecycle (404 / 410)

Rate limited (429)

rate_limit_exceeded from a service and rate_limited from the trust attestor are different things, and neither is a revocation:
  • Service 429 rate_limit_exceeded — you hit a per-route limit. Honor the Retry-After header and back off. See Rate limiting.
  • Attestor 429 rate_limited — you’re minting attestations too fast (the per-binding daily cap). Back off; do not re-link — your binding is fine.

”I revoked, but the agent still works”

Revocation has two levers, each with a deliberate latency (Revocation):
  • Local revoke at a service is immediate at that service but propagates nowhere else — there’s no global revocation bus (§8.3).
  • Global revoke at the attestor stops new attestations, but tokens already minted stay valid until they expire (≤ 15 min). Services that only checked attestation at signup never see it — unless they run attested sessions, which close the gap within the freshness window.
To cut a stolen key off everywhere, act at each service and the attestor. The full runbook is Recover a compromised key.

Still stuck?

Error codes

Every reserved code, status, and trigger.

Security model

Why these boundaries exist.