Skip to content
man glossary/error-190

glossary define error-190

Name

Error 190 (Access Token Invalid)

Error 190 is the Graph API's OAuthException for an access token that has expired, been revoked, been invalidated by a password change or is malformed.

Synopsis

Error 190, OAuthException 190, Invalid OAuth access token

Section

Graph API & SDKs

Level

practitioner

▍

Reviewed

Which token problem do you have?

Question 1 · up to 3

What code is in the error object?

Your answers

None yet — pick an answer to start down the tree.

Path map

Depth 0 of up to 3. Circles are questions, squares are outcomes.

All possible outcomes (7)
  • A permission problem, not a dead token

    The token works but lacks a scope such as whatsapp_business_messaging, or its system user isn't assigned the WABA. Fix scopes or assignment; a new token alone won't help.

    Path: “10, or 200–299”

  • Session ended by a password change

    The user must log in again to get a new token. For servers, switch to a system user token that no person's password can invalidate.

    Path: “190” → “460: password changed”

  • The user hasn't authorised your app

    Send them back through Facebook Login for Business or Embedded Signup to grant access again.

    Path: “190” → “458: app not authorised”

  • The token string itself is wrong

    Look for truncation, quotes or whitespace, and check the header reads Authorization: Bearer followed by the token.

    Path: “190” → “No subcode”

  • The 24-hour temporary token ran out

    Temporary tokens are for testing. Create a system user, assign it the WABA and generate a token for production.

    Path: “190” → “463: expired” → “Temporary token from the App Dashboard”

  • User token expired or revoked

    Refresh it through your login flow or exchange it for a long-lived token, and plan for that one to expire too.

    Path: “190” → “463: expired” → “User access token”

  • System user token expired or revoked

    If it was set to expire, generate a new one and rotate before the date. If it never expires, access was revoked: check whether the system user, its assets or the app were removed.

    Path: “190” → “463: expired” → “System user access token”

Start from the code in the error object and follow the subcode and the token type. Each path ends with the cause and the fix, including the case where it isn't a token problem at all.

Question 1: What code is in the error object? 2 options.

Description

What is error 190?

Error 190 (Access Token Invalid) is the Graph API error returned when the access token sent with a request can't be used. It comes back as an OAuthException with "code": 190, usually with HTTP 401, and covers every way a token can stop working: it expired, the user removed the app, the session was invalidated by a password change or a security checkpoint, or the string isn't a valid token at all. Every Graph API call fails with it, including WhatsApp Cloud API sends, template syncs and media downloads, until a working token is supplied.

The error_subcode tells you which case you are in. Meta documents 463 (expired), 460 (password changed), 467 (invalid access token: expired, revoked or otherwise invalid), 458 (the user has not authorised the app), 459 and 464 (the user must log in to Facebook to clear a checkpoint or confirm the account) and 492 (invalid session). A 190 with no subcode often means a malformed token: truncated when copied, wrapped in quotes, or sent without the Bearer prefix. The message adds detail, as in “Error validating access token: Session has expired on…”.

Error 190 is about whether a token is alive, not what it may do. When a valid token lacks a permission such as whatsapp_business_messaging, or its system user hasn't been assigned the WABA, the Graph API returns permission errors (code 10, or codes from 200 to 299), and a new token without the right API permissions won't help. Lifetimes differ by token type: the temporary token on the WhatsApp page of the App Dashboard lasts 24 hours, user tokens expire (a long-lived access token lasts weeks, not forever), and a system user access token can be generated with no expiry at all.

Key takeaways

  • Error 190 means the access token on the request can't be used: it has expired, been revoked, been invalidated or is malformed.
  • It arrives as an OAuthException, usually with HTTP 401, and the error_subcode says why.
  • Subcode 463 is an expired token, 460 a password change, 467 an invalid token and 458 an app the user hasn't authorised.
  • Production WhatsApp sending should use a system user access token, not the 24-hour temporary token from the App Dashboard.
  • A valid token that lacks a permission returns code 10 or 200–299 instead; regenerate tokens only for 190.

Mechanics

How does error 190 work?

  1. step 1 — Detect it by code, not by status

    Branch on error.code === 190 and its error_subcode in every Graph API client, and mark it non-retryable: the same token will fail again.

  2. step 2 — Inspect the token

    Call GET /debug_token?input_token={TOKEN} with an app access token, or paste it into the access token debugger, to see is_valid, expires_at, scopes and the WABAs in granular_scopes.

  3. step 3 — Apply the fix for the subcode

    463 or 467: issue a new token. 460: the user has to log in again. 458: send the user back through the login or Embedded Signup flow. No subcode: check the token string and the header format.

  4. step 4 — Pause sending and alert

    Stop the queue so messages aren't burned on failures, page the owner, and keep the queue intact for replay once a new token is in place.

  5. step 5 — Move servers to a system user token

    For server-to-server sending, generate a system user token with only the WhatsApp permissions you need, keep it in secrets management, and plan token rotation.

Caveats

Common mistakes with error 190

  • Shipping the temporary token

    The token on the App Dashboard's WhatsApp page is for testing and lasts 24 hours. Production code that uses it fails the next day; use a system user token.

  • Retrying 190 like a transient error

    Generic retry wrappers multiply failures and hide the real alert. Treat 190 as fatal for that token: pause, alert, replace.

  • Regenerating tokens for a permission error

    If the error is code 10 or 200–299, the token is fine and lacks a scope or an asset. Fix permissions or WABA assignment; a fresh token with the same scopes fails the same way.

  • Tying production to a person's login

    A developer's user token dies when they change their password, leave the company or remove the app. Server traffic belongs on a system user that no individual owns.

  • Logging tokens while debugging

    Tokens pasted into logs, tickets and chat are credentials anyone can use. Log the debug_token result (validity, expiry, scopes), never the token itself.

Usage

Error 190 in code

{
"error": {
"message": "Error validating access token: Session has expired on Saturday, 17-Oct-26 14:00:00 PDT. The current time is Saturday, 17-Oct-26 15:12:09 PDT.",
"type": "OAuthException",
"code": 190,
"error_subcode": 463,
"fbtrace_id": "AqLr5Xk2Y8vN3pB"
}
}

Properties

Error 190: key facts and limits

Code and type
190 · OAuthException
HTTP status
401 Unauthorized
Key subcodes
463 expired · 460 password changed · 467 invalid · 458 not authorised
Temporary dashboard token
Expires after 24 hours
System user token
Can be generated with no expiry (expires_at 0)
Not this error
Code 10 or 200–299: permission missing
Retry?
No: replace the token

Example

Example: A weekend outage in Pune

A Pune edtech start-up launches WhatsApp class reminders on a Friday using the temporary token copied from the App Dashboard. On Saturday afternoon every send fails with code: 190, error_subcode: 463: the token had lasted 24 hours. The retry logic hammers the API until 30,000 failed attempts sit in the logs. The fix is a system user in the business portfolio, assigned to the WABA, with a token carrying whatsapp_business_messaging and whatsapp_business_management, stored in a secrets manager, plus a rule that any 190 pauses the queue and pages the on-call developer.

Why it matters

Why does error 190 matter?

190 takes a whole integration down at once: every send, every template sync and every media download fails from the moment the token dies, often at a weekend because a temporary token was shipped to production. Recognising it by code and subcode, instead of retrying it like a network blip, lets you alert immediately, pause the send queue and swap in a valid token before messages pile up or are lost.

Notes

Best practices for error 190

  • Check every token's expires_at with debug_token at deploy time, and alert well before expiry.
  • Grant system users only the WhatsApp permissions and WABAs they need.
  • Store tokens in a secrets manager and reload them without a redeploy.
  • If a 190 makes no sense, send Meta support the fbtrace_id from the error.

Questions

Error 190 (Access Token Invalid) FAQs

What does Graph API error 190 mean?
The access token on the request can't be used: it has expired, been revoked, been invalidated or is malformed. The error_subcode in the response tells you which.
How do I fix “Error validating access token: Session has expired”?
Issue a new token: this is subcode 463. For WhatsApp sending, replace temporary or user tokens with a system user access token so the expiry doesn't recur.
How long does the WhatsApp temporary access token last?
24 hours. It is meant for testing from the App Dashboard; production integrations should use a system user access token instead.
What is the difference between error 190 and error 200?
Error 190 means the token itself is invalid. Codes 10 and 200–299 mean the token is valid but lacks a permission or access to the asset, so the fix is scopes or assignment, not a new token.

See InfiQ pricing

Put Error 190 (Access Token Invalid) to work

InfiQ is an official Meta Business Partner. Start a 7-day free trial — no card needed — and see this running on your own number.