Skip to main content

Exchange Code Attempt Limit Exceeded

exchange_code_attempt_limit_exceeded429

Rate Limiting · Affects all endpoints

Too many failed attempts to exchange the verification code. Wait 1 hour before retrying.

What this means

The exchange code used in OAuth-style flows has been submitted too many times with wrong or invalid values from this IP, and we've locked further attempts for an hour. The retry_after field is 3600 by contract. This is a brute-force defense: it stops an attacker from guessing short-lived codes by exhaustive trial.

When you'll see this

  • A user repeatedly typed the wrong verification code (mistyping the digits or pasting the wrong code).
  • A bug in your client code resubmitted the same code multiple times without realizing it had already been consumed.
  • An attacker tried to guess valid exchange codes by submitting random values.
  • A test or QA flow is exercising the exchange endpoint in a tight loop with invalid codes.
Learn more about how this works

Exchange codes are short-lived single-use tokens issued during authentication flows. They're checked against our server-side store; an invalid submission counts against an IP-scoped attempt budget. Hit the ceiling and we lock further attempts from that IP for an hour, even if the next attempt would have been correct.

In practice: a real user rarely hits this. Most production occurrences are bug-driven — client code that retries an already-consumed code, or a UI that resubmits on Enter without checking what was submitted. The fix is almost always on the client side, not the user's.

Example response

{
"success": false,
"error": "exchange_code_attempt_limit_exceeded",
"message": "Too many failed exchange attempts.",
"details": [],
"retry_after": 3600,
"doc_url": "https://docs.asterwise.com/reference/errors/exchange_code_attempt_limit_exceeded",
"request_id": "req_01HXYZABCDEFGH",
"timestamp": "2026-05-25T12:34:56Z"
}
NEW TO APIS?
Quick fix
  1. Wait 60 minutes. The attempt counter for this IP will reset.
  2. While waiting, check why so many attempts happened. If a user got stuck typing the wrong code, address the input UX. If your client retried automatically, fix the retry logic.
  3. If the user can still authenticate through a different mechanism (a fresh magic link from a different IP), use that path.
PRODUCTION ENGINEER
Recovery pattern

Don't auto-retry on this error. The whole point of the limit is that retrying is what triggered it.

Python:

Production handler

import httpx

def exchange_code(code, base_url, headers):
response = httpx.post(
f"{base_url}/v1/auth/exchange",
headers=headers,
json={"code": code},
timeout=10,
)
if response.status_code == 429:
body = response.json()
if body.get("error") == "exchange_code_attempt_limit_exceeded":
wait_minutes = (body.get("retry_after", 3600)) // 60
return {
"ok": False,
"user_message": (
f"Too many failed verification attempts. "
f"Please wait {wait_minutes} minutes and request "
"a fresh sign-in link."
),
}
response.raise_for_status()
return {"ok": True, "data": response.json()}

Avoid this error by

  • Validate code format on the client (length, charset) before submission. Catching obvious garbage in the UI prevents wasted attempts against the server.
  • Never auto-resubmit the same exchange code. Once a submission returns an error, require the user to take an explicit action before the next attempt.
  • After 3 consecutive failed attempts in your UI, suggest the user request a fresh magic link instead of trying more codes.
  • Don't store exchange codes anywhere durable. They're single-use, short-lived, and should be discarded immediately after submission attempts.