allan-farinas11618 avatar image
allan-farinas11618 asked Patrick Foley commented

Why am I getting this error: TokenInvalid: OAU-213 (Token not found)?

I have an application that downloads recordings using the ruby sdk. I am unable to download any recordings and get an error: OAU-213 (Token not found). The token should be valid since it has not expired.

Can anyone provide any insight why this might be happening?

1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Byrne Reese avatar image
Byrne Reese answered Patrick Foley commented

This answered has been updated to be more current.

Let me attempt to coalesce all the answers to this question into a single cohesive one. The reason for the error is simple, and the error message itself says it all: the access token being use to authenticate with the API is not valid.

However, before I continue with an explanation and an answer, permit me to lay some important semantic groundwork so that one can more easily understand my answer and our documentation.

For OAuth there are two "tokens" that come into play:

  • Authorization code. An "authorization code," or "auth code" for short, is a short-lived token that is exchanged for an access token. We sometimes refer to this as an "auth token" as well.

  • Access token. An "access token" is an actual API credential that is presented in REST API calls via the HTTP Authorization header. You may sometimes see us refer to this an "access key."

You will find that at RingCentral we often refer to both of the above as "tokens" and as a result are unintentionally ambiguous. So be mindful when reading documentation to disambiguate between these terms to avoid confusion.

Back to the question at hand. An access token can become invalid for a few reasons outlined below.

Token has expired Obviously, this is not the problem affecting the user in the original question, as they clearly state their access token has not expired. But for everyone else coming to this question, know that access token expiration is a common challenge faced by developers. Access tokens expire automatically after 24 hours. To keep them fresh, it is essential developers use the refresh token that was acquired when the access token was first issued in order to obtain a new access token.

Tyler Lui has written a stellar Medium post about token management best practices, so I won't burden this answer with all of those details. But suffice it to say, go read it.

Race condition when refreshing tokens One thing developers should be mindful of, as I think developers have a tendency to overlook this, is that the moment a refresh token is used to obtain a new access token, the old access token is immediately invalidated. Here is a scenario I have encountered on multiple occasions:

  • A developer is doing the right thing: they have implemented a service that wakes up once every 12 hours or so, iterates over a list of access tokens and refreshes them in the background.

  • Unbeknownst to them however is that there is an active session somewhere in which an access token is actively being used.

  • So then when the refresh service refreshes the access token, the other session is disrupted because all of a sudden its access token becomes invalidated.

The resolution to this is to implement some kind of locking mechanism on access tokens. That way, while an access token is in use, other services will know not to refresh it.

Too many access tokens issued to the same user Another failure scenario relates to the fact that there is a five access token limit on the number of access tokens that can be issued to the same user and client ID at any point in time. The behavior of the system in this circumstance is not easy to intuit. When the sixth access token is issued under the same client ID and to the same user, the first access token (the oldest) is immediately invalidated.

This is less often a problem for developers utilizing the authorization code flow given the nature of that flow. However, if you are using JWT or even our now deprecated password grant, the probability your code may be impacted by this goes up. The reason is simple: every time you auth to the API via JWT or via a password a new access token is generated. If your code is authored in such a way that you are logging into the API frequently without re-using previous access tokens you have obtained, then you may be unnecessarily proliferating the number of access tokens for any given user. And then you end up hitting this five access token limit, causing older access tokens to be suddenly invalidated.

Sometimes this is happening because you have multiple services or processes all trying to perform various actions for the same user. To debug, audit your whole system looking for services that might be running at the same time. Consider staggering those services, find a way to share access tokens between services, or issue a different client ID and secret to each service running.

1 comment
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Patrick Foley avatar image Patrick Foley commented ·

Hi @Byrne Reese,

I'm migrating from password flow to JWT flow ... using node, how can I reuse the access token after login? I'm calling SDK.login with {jwt} ... but I don't see a reusable token in the object that's returned - do I have to do something else?

If the only consequence is that the oldest existing token is invalidated (meaning the CURRENT login request still succeeds), I don't think it's actually a problem in my case ... but I'm trying to understand better what's really happening. Your answer was very useful in that regard.


0 Likes 0 ·
Tyler Liu avatar image
Tyler Liu answered Tyler Liu commented
Could you please post your code here? (remove credentials before posting)
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

allan-farinas11618 avatar image allan-farinas11618 commented ·

I am using the password flow to authenticate. Here's the code:

 # export RC_SERVER_URL= 
 # export RC_USER_USERNAME= 
 # export RC_USER_PASSWORD=  
 @client = 
 do |config|   
     config.load_env = true 
 response_file = @client.http.get 
 do |req|

response_file.status returns a 401. Here is the response I'm getting back:

    "errorCode" : "TokenInvalid",   
    "message" : "Token not found",   
    "errors" : [ {
        "errorCode" : "OAU-213",
        "message" : "Token not found"   
    } ]
0 Likes 0 ·
Tyler Liu avatar image Tyler Liu ♦ commented ·
You are not taking advantage of the official RingCentral Ruby SDK. Please check it here:
0 Likes 0 ·
vyshakhbabji avatar image
vyshakhbabji Deactivated answered

This issue happens for a couple of reasons:

1. Access token might be expired or another access token would be generated before the current token is expired

2. when the credentials of the user might have changed while the access token would have been still valid

3. The token would have been corrupted

A quick fix for this issue would be to write a business logic :

1. Do not allow to make any API calls when this error is hit

2. Try to refresh the access token so you generate the new pair of the access token and refresh token

3. If the refresh token is not valid/ corrupt, allow the user to authorize once again.

If the above solution doesn't help, Feel free to contact us through a help ticket with full HTTP request and response along with the response headers and with the appID and detailed description of the problem if this issue still persists. My team will get back to you with the right reason, so you can fix your app.

1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Anirban avatar image
Anirban answered

Though all the possible reasons are give above, another condition I like to add is when a valid token is revoked using revoke API (reference) it shows the error message token not found. Since the token is already revoked, it will generate that message

1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Developer sandbox tools

Using the RingCentral Phone for Desktop, you can dial or receive test calls, send and receive test SMS or Fax messages in your sandbox environment.

Download RingCentral Phone for Desktop:

Tip: switch to the "sandbox mode" before logging in the app:

  • On MacOS: press "fn + command + f2" keys
  • On Windows: press "Ctrl + F2" keys