What to do when you suddenly get BAD_REFRESH_TOKEN when trying to refresh an access token



We have one of our applications tightly integrated with HubSpot which means that for quite some requests to our app we do a request over the API to HubSpot. For that we use the Oauth2 authentication scheme. We store our access and refresh token together with the validity period of the access token, when the access token is expired we automatically refresh it using the refresh token.

However, recently, out of the blue, when our app tried to refresh the access token HubSpot returned the status “BAD_REFRESH_TOKEN”. We had to reintegrate our app with HubSpot to get around it (manual intervention!). Unfortunately the HubSpot documentation does not mention this error status at all…

My question is now: Do refresh tokens expire? How can we automatically (without manual intervention) react to such a situation? Un



Hi Raffaele,

Can you give some more information on the request that’s being made with the refresh token? The ‘BAD_REQUEST_TOKEN’ generally indicates a missing/malformed parameter in the request.



Hi Derek

I can tell you the request used to refresh the token. We use the params:
‘form_params’ => [
‘grant_type’ => ‘refresh_token’,
‘client_id’ => $clientId,
‘client_secret’ => $clientSecret,
‘redirect_uri’ => $integrationHubspotRedirectUrl,
‘refresh_token’ => $refreshToken,

I don’t think the request itself is the issue, because the same request is used all the time to successfully refresh the access token.

My main question is: Is there a way for a refresh token to expire?



Hi Derek,

We’re also seeing this problem: at some point (weeks?) after obtaining the refresh token it seems to expire and become unusable. I’m pretty sure, in our case at least, it isn’t a malformed request (because you can make the same request with two different refresh tokens and see the issue with just the older one of the two).

For example, here’s a sample request (secrets redacted) that I can make:

curl https://api.hubapi.com/oauth/v1/token \
-d grant_type=refresh_token \
-d client_id=eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee \
-d client_secret=ffffffff-ffff-ffff-ffff-ffffffffffff \
-d redirect_uri=https://example.com/auth \
-d refresh_token=aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa

When I used a newly obtained refresh token, this works and I get the expected refresh response:


Note that the refresh_token returned in the response is the same (so, we should be able to just keep using the same refresh token over and over to refresh the access token). However, when using a refresh token obtained earlier (some large number of days ago), the refresh token appears to have been expired!

{“status”:“BAD_REFRESH_TOKEN”,“message”:“missing or invalid refresh token”,“correlationId”:“fe6b6231-d2a4-4ff5-897b-e8a0d0dbb218”,“requestId”:“2832b6324e527dc55af26ca7bb1740fd”}

With such a refresh token, the GET endpoint for obtaining more information about the token gives a 404:

curl https://api.hubapi.com/oauth/v1/refresh-tokens/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
{“status”:“error”,“message”:“resource not found”,“correlationId”:“0538d460-6c31-4398-86ac-6d5159d94058”,“requestId”:“200da105d176322d57833d09b1376684”}

But this was a valid refresh token, that was used to refresh the access token successfully at some point previously. Like Raffaele, I’m wondering if there isn’t an accidental refresh_token expiry process that isn’t documented (or if we are expected to e.g. look for a changing refresh token in the response to POST /oauth/v1/token).


We’re also experiencing this intermittent refresh_token invalidation, example request_id a266d68a3c6cc64e7c5145333074cfc4


Hi all,

Refresh tokens do not expire. If you’re seeing a BAD_REFRESH_TOKEN error with a refresh token that was previously shown to be valid, it’s likely that the portal associated with that refresh token uninstalled the integration. If a portal uninstalls the application (or more rarely, a portal expires) then refresh tokens are invalidated. There’s only one refresh token per app per portal, so if a user re-auths the integration it will also invalidate the first refresh token.


we have the same problem, we refresh the token when it expires. Everything is fine apart from some occasions when we get BAD_REFRESH_TOKEN.



it happened to us as well, we just used the token yesterday all day, and then we left everything for more than 6 hours. then try to get a new token with the refresh token we had and we got the same error (nobody unistalled anything or altered anything in any way, since im the only one who has access, an i can assure you i didn’t touch the computer :stuck_out_tongue: )


my bad, intead of refresh_token was using authorization_code in grant_type