Getting { "error" : "invalid_grant" } when getting access token from a refresh token

32,404 views
Skip to first unread message

Maleka Sehori

unread,
Mar 24, 2014, 12:49:56 PM3/24/14
to google-doubleclick-...@googlegroups.com
Hi,

I am using DFA Reporting API and OAuth flow for reporting. Basically, my application requires user interaction just once to grant access, get the auth code and retrieve and store refresh token.  There after,  stored refresh token is used to generate access token to use the api. But for particular credentials, it gives invalid grant error as seen below everyday and the user has to follow the oauth flow everyday. 

Error communicating with accounts.google.com/o/oauth2/token 
Server at /o/oauth2/token not found. (HttpStatus = 400) 
{ "error" : "invalid_grant" } 


is the grant being revoked everyday ? Any idea? 

Thanks,
Maleka S

Jonathon Imperiosi (DFA API Team)

unread,
Mar 24, 2014, 2:34:14 PM3/24/14
to google-doubleclick-...@googlegroups.com
Hi Maleka,

There are 2 common problems that cause invalid_grant errors:

1. Your server's clock is out of sync with NTP
2. You've exceeded the refresh token limit

Unfortunately the OAuth2 documentation on our developer site isn't very centralized, but this is covered in a few places (see here, as an example). I'd suggest investigating whether either of these issues could be the source of your problem.

Regards,
- Jonathon Imperiosi, DFA API Team

Maleka Sehori

unread,
Apr 11, 2014, 12:06:50 PM4/11/14
to google-doubleclick-...@googlegroups.com
Hi Jonathan, 

Regarding, server's clock out of sync: I have around multiple dfa connections running on the same server but for some reason there is this particular bunch of connections that go into error every day. 

Regarding exceeding the refresh token, I have a refresh token stored in the database and use it to create new access token. I have setup one client for installed application which is used by multiple users. How do I investigate if I am exceeding the limit ? And also, is there a check that can be performed to avoid this error to occur?

Thanks, 
Maleka S

Jonathon Imperiosi (DFA API Team)

unread,
Apr 14, 2014, 9:36:42 AM4/14/14
to google-doubleclick-...@googlegroups.com
HI Maleka,

If you're using a single refresh token to generate access tokens frequently, then this could be the root of the problem. Unfortunately there isn't an easy way to tell if you're hitting the limit. When you begin to generate too many tokens, the oldest valid tokens are silently invalidated, which means there are no errors to alert you that there may be a problem. You would need to keep track of the tokens yourself, as well as the times they are created/invalidated to know for sure.

In general, we suggest trying to limit the number of access tokens you use to prevent running into these limits. This can be accomplished by caching access tokens and reusing them (across threads/users/etc) until they expire, or limiting the number of tokens your application generates for simultaneous use to say 15 or 20.

Regards,
- Jonathon Imperiosi, DFA API Team

z.shishmano...@gmail.com

unread,
May 12, 2014, 4:16:49 AM5/12/14
to google-doubleclick-...@googlegroups.com
Hi All,
I have the same problem with retrieving of refresh token for oauth2 with php/curl, I try to retrieve it doing step by step as described here https://developers.google.com/android-publisher/authorization, but on point 4 I have problem
"4. Exchange this code for an access and refresh token pair by sending a POST request to https://accounts.google.com/o/oauth2/token with the following fields set:"


define ('OAUTH_TOKEN_URL',         'https://accounts.google.com/o/oauth2/token');
define ('OAUTH_GRANT_TYPE',       'authorization_code');
define ('OAUTH_CODE',                   'This Code Is Hidden By Me');
define ('OAUTH_CLIENT_ID',            'This Code Is Hidden By Me');
define ('OAUTH_CLIENT_SECRET',  'This Code Is Hidden By Me');
define ('OAUTH_REDIRECT_URI',     'http://projects.snapp.info/ecr2/response.php');



    //-------------------------------------------------------------------------
    private function getAccessRefreshToken () {
        $authTokenUrl = OAUTH_TOKEN_URL;
       
        $parameters['grant_type']    = OAUTH_GRANT_TYPE;
        $parameters['code']          = OAUTH_CODE;
        $parameters['client_id']     = OAUTH_CLIENT_ID;
        $parameters['client_secret'] = OAUTH_CLIENT_SECRET;
        $parameters['redirect_uri']  = OAUTH_REDIRECT_URI;
       
        return $this->doPostCURL($authTokenUrl, $parameters);
    }

    //-------------------------------------------------------------------------
    protected function doPostCURL($url, $parameters) {
        //open connection
        $ch = curl_init();
       
        //set the url, number of POST vars, POST data
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_VERBOSE, 0);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible;)");
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);
        curl_setopt($ch, CURLOPT_URL, $url);

        //execute post
        $result = curl_exec($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if ($code == 200) {
            $result = json_decode($result, TRUE);
        }
        else {
            echo "===ERROR CODE START===================\n";
            echo $code;
            echo "\n===ERROR CODE END===================\n\n";
        }
       
        curl_close($ch);
       
        return $result;
    }


Here is the result of execution of the code above:


===ERROR CODE START===================
400
===ERROR CODE END===================

string(511) "HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Date: Mon, 12 May 2014 08:05:17 GMT
Content-Disposition: attachment; filename="json.txt"; filename*=UTF-8''json.txt
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Alternate-Protocol: 443:quic
Transfer-Encoding: chunked

{
  "error" : "invalid_grant"
}"


I have checked server clock synchronization:

zdr@inspiron:/etc# ntpdate ntp.ubuntu.com
12 May 11:11:40 ntpdate[4890]: adjust time server 91.189.89.199 offset 0.009995 sec

Is the time offset normal? Even the server clock is synchronized, the system returns me the same error.

Can you please give me an advice for resolving of this issue?

Thanks.

Best Regards
Zdravko Shishmanov

Jonathon Imperiosi (DFA API Team)

unread,
May 14, 2014, 10:20:55 AM5/14/14
to google-doubleclick-...@googlegroups.com
Hi Zdravko,

It sounds like you're getting this error earlier in the process than the previous poster, so the suggestions I made may not apply here. It also seems that you're following instructions for a different API, which may or may not be causing issues.

To start, I would suggest reading over these instructions, instead. Make sure you're requesting an authorization code for the correct scope(s), depending on the DFA API(s) you plan to use. Also note that the authorization code you receive from the initial authenticate request can only be used once, so you may need to repeat that step multiple times while testing (until you get the next step to succeed).

If you're still running into issues, you may want to try using the OAuth 2.0 Playground to step through the auth flow, and examine the HTTP request/response at each step. This usually helps pinpoint where an application is passing the incorrect info.

Regards,
- Jonathon Imperiosi, DFA API Team

Zdravko Shishmanov

unread,
May 16, 2014, 3:25:50 AM5/16/14
to google-doubleclick-...@googlegroups.com
Thank you!
I will follow you advices.

Best Regards
Zdravko Shishmanov


--
You received this message because you are subscribed to a topic in the Google Groups "Google's DoubleClick for Advertisers API Forum" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-doubleclick-for-advertisers-api/FZo-6ZZGeyQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to google-doubleclick-for-ad...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

jane0...@gmail.com

unread,
Dec 27, 2016, 12:18:28 PM12/27/16
to Google's DoubleClick Campaign Manager API Forum
Hi,

I am also working on an application which uses google shopping API. For each request, API needs a refresh token to communicate with google api. So as per Google API, I have got the refresh token and using it in request. But system is showing me the error as "invalid_grant". I have searched lot of things but still stucked. Some place I have found that, refresh token must be started with "1/" and my refresh token stats with "4/".

So, I want to know that is this problem with refresh token or something else. If my refresh token is not vali then why the google api returning me the incorrect refresh token.

Please anyone tell me what is the exact issue? Thanks in Advance

Jonathon Imperiosi (DCM API Team)

unread,
Dec 28, 2016, 9:44:37 AM12/28/16
to Google's DoubleClick Campaign Manager API Forum
Hi there,

It sounds what you have is actually an authorization code, not a refresh token. In general, refresh tokens begin with 1/..., as you've found.

The code you have is used to authorize your app to make requests on behalf of a Google account. Your app will need to exchange this code for an access/refresh token pair, which you can then use to make requests. There's more info about this process in the OAuth 2.0 guide. You can also take a look at our code samples, which use the official Google API client libraries to handle this process automatically.

Regards,
- Jonathon Imperiosi, DCM API Team

ty...@bizible.com

unread,
Aug 15, 2018, 4:38:34 PM8/15/18
to Google's DoubleClick Campaign Manager API Forum
Hello,

I am experiencing issues when trying to retrieve a token when I use my refresh token.
I am managing several Double Click accounts, and I seem to only be having a problem with one of them..
I highly doubt its a problem with the request itself since it works for the majority of my clients, but I have listed the request as well as the error response below.

Request:

User-Agent: google-api-dotnet-client/1.35.1.0 (gzip)
Content-Type: application/x-www-form-urlencoded
Content-Length: 208
Connection: Keep-Alive

refresh_token=1%2F{omitted}&grant_type=refresh_token&client_id={omitted}&client_secret={omitted}

Response:

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Vary: X-Origin
Vary: Referer
Date: Tue, 14 Aug 2018 02:02:04 GMT
Server: ESF
Cache-Control: private
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Alt-Svc: quic=":443"; ma=2592000; v="44,43,39,35"
Accept-Ranges: none
Vary: Origin,Accept-Encoding
Transfer-Encoding: chunked

44
{
  "error": "invalid_grant",
  "error_description": "Bad Request"
}
0

Since I have been requesting the same permissions from all my of clients, I'm guessing that i has to do something with the permissions that the authenticating user possesses from the business...
But I can't seem to find any information that seems to look wrong when I asked my client.
I understand that without the token itself, you most likely will not be able to look into this issue any further..
Is there anything in the request that's obviously wrong, or is there anything you know that may cause this combination of error messages?
Otherwise, is there a secure way for me to send you the information you need to look into this further?

Dhanya Sundararaju (DFA API Team)

unread,
Aug 16, 2018, 2:27:13 PM8/16/18
to Google's DoubleClick Campaign Manager API Forum
Hello,

The "invalid_grant" error usually indicates that the access or refresh token being passed in your request is incorrect or invalid. To verify that your credentials are correct, you can try the CURL request provided below and see if you are able to generate the access tokens. If the credentials are correct, you should get an access token for the below request:

curl https://www.googleapis.com/oauth2/v4/token \
-d refresh_token=your-refresh_token \
-d client_id=your-client-id \
-d client_secret=your-client-secret \
-d grant_type=refresh_token

If your credentials are incorrect and still facing issue then you can generate a new refresh token with the help of this guide and retry your request. Please let me know if the issue persists.

Regards,
Dhanya, DCM API Team
Reply all
Reply to author
Forward
0 new messages