Hey folks,
One of our users is consistently getting this error when we try to refresh their access token via POST ``https://api.hubapi.com/oauth/v1/token:
{
"error": "invalid_grant",
"error_description": "missing or invalid refresh token",
"status": "BAD_REFRESH_TOKEN"
}
We’ve already gone through the usual suspects:
- App is not uninstalled from their portal, the installation is active.
- Connected user is a Super Admin.
Re-authenticating fixes it temporarily, but the error comes back again after a while. So it’s not a one-time thing, the refresh token keeps getting invalidated somehow.
We tried checking the auth logs in the legacy app monitoring dashboard but it’s not accessible, just showing a migration prompt. We’re planning to migrate to the new app framework soon, but need to unblock this user in the meantime.
Any help would be appreciated!
Hey @activepieces and welcome, we are so glad to have you here! 
Thanks for reaching out to the HubSpot Community!
It’s great to know the steps/verifications you have already taken. And glad to hear that it gets fixed with re-authentication, even if I understand that’s not ideal. Now, let’s see how we can help!
To start with, here are a few things to check:
- Are you storing and using the new refresh token from every /oauth/v1/token response?
- Are you avoiding simultaneous refreshes from multiple servers or processes?
- Are you refreshing tokens only when needed (i.e., when expires_in is reached)?
Also, I’d love to hear from our Top Experts: Hi @Anton, @zach_threadint and @coldrickjack do you have suggestions to help @activepieces, please?
On a side note, it’s great to hear that you are planning the migration to /oauth/2026-03/token soon because /oauth/v1/token is indeed deprecated and will be sunset on February 16, 2027.
Here is the documentation for reference:
Thanks so much and have a wonderful day!
Bérangère
This post was created with the assistance of AI tools
Hi @activepieces 
That’s a strange one. From memory, this sort of inconsistency is not something I’ve seen before with the V1 OAuth endpoints. Generally speaking, refresh tokens are unique per combination of HubSpot User + HubSpot Portal. At least in my experience, even if a specific user installs an app several times within a single HubSpot Portal, the resulting refresh token generally will remain the same. Is this consistent with your experience?
Also, a few things to clarify that might help the community troubleshoot this with you:
- Please share with us more information relating to the requests that fail and those that succeed (e.g. request header(s), JSON body). Please be sure to not expose any sensitive information (e.g. redact refresh token and client secret values).
- How are you storing and retrieving your refresh tokens (e.g. user-specific vs. portal-specific, favour most recent etc.)?
- How many different app users have installed the app in the affected portal?
Please let me know if you have any follow-up questions.
Hi @Bérangère and @coldrickjack, thanks for the detailed responses!
To answer your questions:
- Storing new refresh token — Yes, we store the new refresh token from every response.
- Refreshing only when needed — Yes, we only refresh when the token is actually expired.
- Simultaneous refreshes — We suspect this could be a factor and are currently investigating internally with our team.
@coldrickjack — great point on refresh token uniqueness, that’s helpful context. To your follow-up questions:
- Failing vs succeeding requests — Here’s the request format we send to
https://api.hubapi.com/oauth/v1/token:
POST https://api.hubapi.com/oauth/v1/token
Content-Type: application/x-www-form-urlencoded
Accept: application/json
grant_type=refresh_token&refresh_token=<redacted>&client_id=<redacted>&client_secret=<redacted>
The response on failure:
{
"error": "invalid_grant",
"error_description": "missing or invalid refresh token",
"status": "BAD_REFRESH_TOKEN"
}
- How we store and retrieve refresh tokens — We store one refresh token per connected user (not per portal), encrypted, and always use the most recently received token.
- How many app users have installed in the affected portal — Checking with the affected users and will follow up.
Also appreciate the heads up on the deprecation timeline — migration is already on our roadmap!
Hi @activepieces and thanks for your patience!
It sounds like you’re encountering a race condition with concurrent refresh token requests.
HubSpot uses refresh token rotation, so whenever a token is used, a new one is issued and the previous one becomes invalid. If two processes try to refresh at the same time, one will succeed, but the other will get a BAD_REFRESH_TOKEN error since the token was just rotated.
Here is what you can try:
It’s a good idea to implement a distributed lock or mutex around your refresh logic to ensure that only one process can refresh a given user’s token at a time. Once you have the lock, double-check if the token was already refreshed before you proceed.
Consider storing tokens per HubSpot account (portal) rather than per user, as recommended in our OAuth token management guide. This can help prevent race conditions if multiple users in the same portal trigger refreshes close together.
Hi @zach_threadint, @SteveHTM and @evaldas do you have additional suggestions, please?
Thanks so much,
Bérangère
This post was created with the assistance of AI tools