Authaz logoAuthaz
DocumentationAPI Reference
  • Get Started

    • Authaz
    • Core Concepts
    • Set up your app
    • Quickstart — cURL
  • Authentication

    • Authentication Settings
    • Signup
    • Invitations
    • Password Authentication
    • Multi-Factor Auth
    • Magic Link
    • OAuth / Social Login
    • Passkey (WebAuthn)
    • SAML SSO
    • Machine-to-Machine (M2M)
    • API Keys
  • Authorization

    • Authorization
    • Resources
    • Policies
    • Roles
    • Access Explorer
  • Tenancy

    • Multi-tenancy
    • Tenancy Customization
  • Brand & Host

    • Branding
    • Custom Domains
    • Communications & Email Templates
  • Operate

    • Users
    • Analytics
    • Audit Logs
    • Application Settings
  • SDK Quickstarts

    • Quickstart — Next.js
    • Quickstart — React SPA
    • Quickstart — Hono
    • Quickstart — .NET (Authaz.Sdk)
  • Recipes

    • Recipes & Cookbook
    • Next.js — first integration
    • Next.js — B2B SaaS (multi-tenant)
    • Hono — first integration
    • Hono — B2B SaaS (multi-tenant)
    • React SPA — first integration
    • React SPA — B2B SaaS (multi-tenant)
    • .NET — first integration
    • .NET — B2B SaaS (multi-tenant)
  • Reference

    • Tokens
    • API Reference
    • Errors & Troubleshooting
  • Documentation

    • How Authaz is Built
  1. Authaz
  2. Docs
  3. Reference
  4. Errors & Troubleshooting

Reference

Errors & Troubleshooting

6 min read·Updated Jun 19, 2026

A reference for every error Authaz returns. Use it like a debugger: search the page (⌘F / Ctrl+F) for the exact code or message your app is seeing, find the cause, apply the fix.

If your specific error isn't here, the API reference has the canonical response shape and HTTP status semantics.

Sign-in flow errors (OAuth / OIDC)#

These are returned by the OAuth endpoints (/oauth2/authorize, /oauth2/token, /oauth2/userinfo).

CodeStatusMost likely causeFix
invalid_request400The redirect_uri your code sends doesn't match what's registered in Settings → Redirect URIs. The #1 OAuth onboarding bug.Compare exactly: trailing slash, port, http vs https, scheme. Add every dev/staging/prod URL.
invalid_grant400The authorization code was already used. Codes are single-use.Restart the flow to get a fresh code.
invalid_grant400The authorization code expired (default: 60 seconds).Restart the flow. If this happens often, your callback handling is too slow — exchange the code immediately on receipt.
invalid_grant400The code_verifier you sent doesn't match the original code_challenge.Make sure your verifier is generated before the auth request and re-used in the token request. PKCE pairs are per-flow.
invalid_grant400The refresh token was already used (refresh-token rotation invalidates the previous one).Replace your stored refresh token with the new one returned on every refresh.
invalid_client401Wrong client_id, or you're sending a client_secret for a PKCE-only public client.Public clients (browser/mobile) use PKCE only — don't send client_secret. Confidential backends send both.
invalid_client401The AUTHAZ_CLIENT_SECRET env var is wrong, missing, or you swapped Application ID and Client Secret.Re-copy from Settings → API Keys. Sanity-check by echo $AUTHAZ_CLIENT_SECRET (length should match the dashboard value).
invalid_token401The access token expired (default lifetime: 15 minutes).Use the refresh token to get a new pair. The SDKs do this automatically when autoRefresh is on.
invalid_token401The access token's signature didn't verify.Check that you're using the right JWKS endpoint for the application. Don't accept tokens issued by a different Authaz application.
unsupported_response_type400You're trying to use the implicit or password grants.Authaz only supports the auth-code + PKCE and refresh-token flows for user auth, plus client-credentials for M2M.
account_locked403The user failed too many login attempts. Returns { "error": "account_locked", "retryAfter": 900 }.Wait the seconds in retryAfter, or unlock manually via POST /api/v1/users/{userId}/unlock. See Password.
password_breached422Breach detection rejected a password that appeared in a known data breach.The user must pick a different password. Authaz only sends the first 5 hex chars of the SHA-1 hash to HaveIBeenPwned.
mfa_required401The user has MFA enabled but didn't complete the second factor.Authaz Sign-In adds the MFA step automatically. If you're scripting against the OAuth endpoints directly, hit the MFA challenge endpoint between password and token exchange.

Management API errors#

Returned by every /api/v1/... endpoint. The response body always has code, message, and (for validation errors) field.

Statuscode examplesMost likely causeFix
401unauthenticated, invalid_api_key, expired_tokenMissing, wrong, or expired credentials.Verify X-API-Key (Management API key) or Authorization: Bearer (user JWT) is set and current.
403forbidden, insufficient_permissionsCredentials valid, but the API key lacks the permission for this endpoint.Grant the permission to the key in Dashboard → API Keys, or use a key that already has it.
403tenant_mismatchThe credential is scoped to a different tenant than the resource.Either use a credential scoped to the right tenant, or switch to a global Management API key.
404not_foundResource doesn't exist, OR exists but is in a tenant your credential can't see.If you're sure it exists, check the credential's tenant scope — 404 is intentionally indistinguishable from 403 to prevent enumeration.
409conflict, email_already_existsDuplicate resource. Most common: creating a user/invitation with an email already in use.Search first (GET /users?search=email@…) and decide whether to update or skip.
422validation_errorRequired field missing, format wrong, or value out of range. field names the offending input.Check the field's schema in the API reference.
429rate_limitedToo many requests. Returns Retry-After (seconds).Back off and retry. SDKs do this automatically with the standard resilience handler.
500+internal_error, service_unavailableServer-side problem.Safe to retry idempotent calls with exponential backoff. Persistent 5xx — contact support.

Multi-tenant errors#

Code / symptomMost likely causeFix
no_tenant (403)The user signed in but didn't pick a tenant — the access token has no tenant_id claim.Send them back through /api/auth/login to re-pick. Tenant binding happens at sign-in, not at runtime.
tenant_mismatch (403)An authorization check ran without a tenant_id, or with the wrong one.Always pass tenant_id from the access token to every POST /api/v1/authorization/check. Never read it from a header, query, or body.
Cross-tenant data leakYour code keyed a session cache by userId alone. The same user can have different roles in different tenants.Key session caches by (userId, tenantId).

SDK errors (TypeScript / JavaScript)#

SymptomSurfaceFix
useAuthaz must be used within AuthazProviderReact<AuthazProvider> doesn't wrap the component using the hook. Move it higher in the tree.
useAuthaz() stuck on isLoading: trueReact / Next.jsbasePath prop on AuthazProvider doesn't match where the backend mounted the auth handler. Default is /api/auth.
/api/auth/me returns 401 immediately after loginNext.js / HonoThe OAuth callback page (/auth/callback) didn't re-POST the code into the handler. See the callback page in the Next.js quickstart.
Logged in, but a hard refresh signs the user outReact SPASession cookie isn't reaching the backend — same-site or cross-origin issue. In dev, use the Vite proxy. In prod, host frontend and backend under the same registrable domain.
process.env.X is undefined on Cloudflare Workers / BunHonoThose runtimes don't auto-populate process.env. Pass env via wrangler.toml (Workers) or bun --env-file=.env.

SDK errors (.NET — Authaz.Sdk)#

SymptomFix
Every call returns AuthazError.Unauthorized (401)API key wrong, missing, or you used the OAuth Client Secret. Management API needs mgmt_01h… from Settings → API Keys → Management.
AuthazError.Network on every callWrong BaseAddress, no internet, or DNS / firewall. Confirm https://your-app.authaz.io is reachable.
result.Value is null after IsSuccess == trueThe endpoint returns no body (e.g. delete). Value is only populated on endpoints that return data.
AuthazError.NotFound for an ID you just createdWrong tenant or organization scope. The ID must belong to the same scope as the API key.
DI throws Unable to resolve service for IAuthazClientAddAuthazSdk not called, or called after var app = builder.Build();. Register before Build().

Network and infrastructure#

SymptomCauseFix
TLS / cert error on your-app.authaz.ioCustom domain isn't verified yet, or DNS hasn't propagated.Check Settings → Custom Domains. New domains take up to ~24h to issue a certificate.
CORS errors on /api/auth/me from a SPAFrontend and backend on different origins, no proxy or CORS config.In dev, prefer same-origin via Vite/Next proxy. In prod, host both under the same registrable domain.
Behind a load balancer, cookies aren't SecureThe app doesn't see HTTPS because the LB terminates it.Forward x-forwarded-proto: https so the SDK detects HTTPS.
/.well-known/jwks.json returns 404Wrong host. The JWKS lives at the application's per-app subdomain.Use https://your-app.authaz.io/.well-known/jwks.json — replace your-app with your application's slug.

When to contact support#

Open a ticket if:

  • The error consistent reproduces but isn't listed here.
  • You're seeing 5xx for >5 minutes against your application's host.
  • Audit logs show a sign-in event that you can't account for (security concern).
  • Tokens you minted with one SDK version stop verifying after upgrading.

Include: the application ID, the timestamp (UTC), the request path, the full error body (it's safe — error responses don't leak secrets), and what you've already tried.

Previous
API Reference
Next
How Authaz is Built