401 error "Credentials failed to obtain metadata"

599 views
Skip to first unread message

Ellen Skipper

unread,
Nov 26, 2021, 5:40:54 AM11/26/21
to AdWords API and Google Ads API Forum
Hi,

I'm working on a tool which has localdev, dev, staging and prod environments. We use the same credentials (client ID, client secret, refresh token and developer token) across localdev, dev and staging.

Recently we've begun seeing an auth error on staging, when sending to either of our two test accounts, which share the same master account. We do not see this error on localdev or dev. The prod site hasn't been in use since we saw this issue so we don't know whether prod is also affected.

We are running the same build on both dev and staging sites. We also recently upgraded to Ads API v9 from v7, but we were seeing this error on staging both before and after we released the update to staging. We've also checked the auth values on staging are being passed through to the service correctly and they are exactly the same as on the dev service.

Do you have any idea what might be causing this, please?

See logs below:
2021-11-26 10:21:33,185 WARN  c.g.a.googleads.lib.request.summary [grpc-default-executor-0] - FAILURE REQUEST SUMMARY. Method: google.ads.googleads.v9.services.AdGroupAdService/MutateAdGroupAds, Endpoint: googleads.googleapis.com:443, CustomerID: xxxxxxxx, RequestID: null, ResponseCode: UNAVAILABLE, Fault: Credentials failed to obtain metadata.
2021-11-26 10:21:33,185 INFO  c.g.ads.googleads.lib.request.detail [grpc-default-executor-0] - FAILURE REQUEST DETAIL.
2021-11-26T10:21:33.186+00:00 Request
2021-11-26T10:21:33.186+00:00-------
2021-11-26T10:21:33.186+00:00 MethodName: google.ads.googleads.v9.services.AdGroupAdService/MutateAdGroupAds
2021-11-26T10:21:33.186+00:00 Endpoint: googleads.googleapis.com:443
Headers: {developer-token=REDACTED, login-customer-id=xxxxxxxxx, x-goog-api-client=gl-java/11.0.13 gccl/task ':google-ads:jar' property 'archiveVersion' gapic/task ':google-ads:jar' property 'archiveVersion' gax/2.6.1 grpc/task ':google-ads:jar' property 'archiveVersion'}
......
Response
--------
Headers: null
Body: null
Failure message: null
Status: Status{code=UNAVAILABLE, description=Credentials failed to obtain metadata, cause=com.google.api.client.http.HttpResponseException: 401 Unauthorized
POST https://oauth2.googleapis.com/token
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1116)
at com.google.auth.oauth2.UserCredentials.doRefreshAccessToken(UserCredentials.java:273)
at com.google.auth.oauth2.UserCredentials.refreshAccessToken(UserCredentials.java:190)
at com.google.auth.oauth2.OAuth2Credentials$1.call(OAuth2Credentials.java:257)
at com.google.auth.oauth2.OAuth2Credentials$1.call(OAuth2Credentials.java:254)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
}.

Google Ads API Forum Advisor

unread,
Nov 28, 2021, 9:45:59 PM11/28/21
to ellen....@softwire.com, adwor...@googlegroups.com

Hi Ellen,

 

I'm Kevin from the Google Ads API Team.

 

Can you please provide a set of complete request and response logs with request ID which succeeded and another set of logs which failed so I can take a closer look at the issue? For your reference, here's our guide on how to enabled detailed logging for the Java client library.

 

You can send these to me via Reply privately to author option. If this option is not available to you, then you may send it directly to googleadsa...@google.com, just let me know in this thread once you have sent it so I can check on our end.

 

Regards,

Reminder: Share your feedback about the Google Ads (AdWords) API! Take the 2021 Google Ads API and AdWords API Annual Survey
 

Google Logo
Kevin Gil Soriano
Google Ads API Team
 


ref:_00D1U1174p._5004Q2RwIwS:ref

Ellen Skipper

unread,
Mar 30, 2022, 5:05:13 AM3/30/22
to Google Ads API and AdWords API Forum
Update on this: 
Google support team helped us identify that because no request ID was assigned to our requests, this must be an issue early in the process, ie at OAuth stage, before the request reached Google Ads.
It turned out that we had a hidden  %0A linefeed character which was lost when displaying the secret value in AWS console/in debugging logs, but caused the auth to fail (we didn't have direct access to edit the secret value so this took a long time to flush out). We found this by adding a lot of extra logging, and noticed it in the URL encoded request body:

log.info("Client Id: " + gaClientId); 
CloseableHttpClient client = HttpClients.createDefault(); 
HttpPost httpPost = new HttpPost("https://oauth2.googleapis.com/token"); 
List<NameValuePair> params = new ArrayList<>(); 
params.add(new BasicNameValuePair("client_id", gaClientId)); 
params.add(new BasicNameValuePair("client_secret", gaClientSecret)); 
params.add(new BasicNameValuePair("grant_type", "refresh_token")); 
params.add(new BasicNameValuePair("refresh_token", gaRefreshToken)); 
UrlEncodedFormEntity requestBody = new UrlEncodedFormEntity(params); 
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
requestBody.writeTo(outputStream); 
log.info("Request Body: " + outputStream); 
outputStream.close(); 
httpPost.setEntity(requestBody); 
CloseableHttpResponse response = client.execute(httpPost); 
log.info("Status Code: " + response.getStatusLine().getStatusCode()); 
log.info("Reason Phrase: " + response.getStatusLine().getReasonPhrase()); 
log.info("Response Body: " + EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8));
client.close();
Reply all
Reply to author
Forward
0 new messages