Skip to content
This repository was archived by the owner on May 12, 2026. It is now read-only.
This repository was archived by the owner on May 12, 2026. It is now read-only.

IllegalArgumentException when parsing token #1027

Description

@petedmarsh

Thanks for stopping by to let us know something could be better!

PLEASE READ: If you have a support contract with Google, please create an issue in the support console instead of filing on GitHub. This will ensure a timely response.

Please run down the following list and make sure you've tried the usual "quick fixes":

If you are still having issues, please include as much information as possible:

Environment details

  1. GCE / ComputeEngineCredentials
  2. OS type and version:
  3. Java version: 11
  4. version(s):

Steps to reproduce

Occasionally we see errors refreshing a token, with the actual source of the error being:

https://github.com/googleapis/google-http-java-client/blob/9f389ef89195af77eff8f1e1c1c9ee9bf9c7792c/google-http-client/src/main/java/com/google/api/client/json/webtoken/JsonWebSignature.java#L544

Following through the code I get back to here

public IdToken idTokenWithAudience(String targetAudience, List<IdTokenProvider.Option> options)
:

    GenericUrl documentUrl = new GenericUrl(getIdentityDocumentUrl());
    if (options != null) {
      if (options.contains(IdTokenProvider.Option.FORMAT_FULL)) {
        documentUrl.set("format", "full");
      }
      if (options.contains(IdTokenProvider.Option.LICENSES_TRUE)) {
        // license will only get returned if format is also full
        documentUrl.set("format", "full");
        documentUrl.set("license", "TRUE");
      }
    }
    documentUrl.set("audience", targetAudience);
    HttpResponse response = getMetadataResponse(documentUrl.toString());
    InputStream content = response.getContent();
    if (content == null) {
      throw new IOException("Empty content from metadata token server request.");
    }
    String rawToken = response.parseAsString();
    return IdToken.create(rawToken);

So - purely speculating - it looks to me that the HTTP request may sometimes not error out but instead return a non-200 response with an error in the body which is then not parsable as a token. I have no proof of this but it seems plausible based on the code.

If this is happening IMO it would be better to have a more specific error, the IllegalArgumentException is very odd and confusing, though of course the end result is the same (i.e. the token is not refreshed).

Code example

// example

Stack trace

java.lang.IllegalArgumentException: null
	at com.google.common.base.Preconditions.checkArgument(Preconditions.java:131)
	at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:35)
	at com.google.api.client.json.webtoken.JsonWebSignature$Parser.parse(JsonWebSignature.java:544)
	at com.google.api.client.json.webtoken.JsonWebSignature.parse(JsonWebSignature.java:479)
	at com.google.auth.oauth2.IdToken.create(IdToken.java:80)
	at com.google.auth.oauth2.IdToken.create(IdToken.java:68)
	at com.google.auth.oauth2.ComputeEngineCredentials.idTokenWithAudience(ComputeEngineCredentials.java:261)
	at com.spotify.eventsender.grpc.DefaultIdTokenProvider.idTokenWithAudience(DefaultIdTokenProvider.java:25)
	at com.google.auth.oauth2.IdTokenCredentials.refreshAccessToken(IdTokenCredentials.java:124)
	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(FutureTask.java:264)
    ...

External references such as API reference guides

  • ?

Any additional information below

Following these steps guarantees the quickest resolution possible.

Thanks!

Activity

  1. TimurSadykov commented on Oct 26, 2022

    @TimurSadykov

    Thanks for reporting! without checking the response status, the code indeed looks incorrect

  2. added
    type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.
    priority: p2Moderately-important priority. Fix may not be included in next release.
    on Oct 26, 2022
  3. kberezin-nshl commented on Aug 29, 2023

    @kberezin-nshl

    Just wasted several hours being stuck with the same problem...

    The root cause of the issue in my case with ComputeEngineCredentials was that I was actually getting the following response:

    404 Not Found
    identity token not available for default service account; please provide a user-specified service account
    

    But this code here doesn't check if response was successful at all. It was just passing "identity token not available for default service account; please provide a user-specified service account" string forward to JsonWebSignature parser and the latter crashed.

    This pull request partially addressed the issue but it only covers 503 response code and as you can see in my case it was 404 response code.

    In other words, I think the right fix would be to make sure that the response is 2xx before proceeding with token creation and throw an exception otherwise.

    cc @TimurSadykov

    EDIT: not sure how many various *Credentials classes are affected by the same problem

  4. TimurSadykov commented on Aug 29, 2023

    @TimurSadykov

    @kberezin-nshl Thanks for investigating. The fix that you have mentioned was indeed a short-term fix for the most common case. We will consider a proper fix. It would help if you share any stats/scenario when you get a repro of the error? Thanks!

  5. kberezin-nshl commented on Aug 29, 2023

    @kberezin-nshl

    @TimurSadykov sure.

    In my case, I tried to follow this guide to get a token in order to access IAP-protected resource from Cloud Build environment.

    Here's shortened version (will crash if run in Cloud Build using default service account):

    public class BuildIapRequest {
      private static final String IAM_SCOPE = "https://www.googleapis.com/auth/iam";
    
      private BuildIapRequest() {}
    
      public static void thisMethodWillCrash() throws IOException {
        GoogleCredentials credentials =
            GoogleCredentials.getApplicationDefault().createScoped(Collections.singleton(IAM_SCOPE));
    
        // the method bellow will eventually call ComputeEngineCredentials.idTokenWithAudience
        // which will get 404 and pass error message to token parser
        credential.getRequestMetadata("your_iap_protected_url"); 
      }
    }
    
  6. self-assigned this
    on Aug 30, 2023
  7. Martin4R commented on Apr 30, 2024

    @Martin4R

    This is the only issue ticket mentioning the error message "please provide a user-specified service account" when trying to get an ID-token via the metadata endpoint within a VM.
    In my case the issue was, that I tried to use a VM (in VertexAI) with a user-specified service account, but my service account did not have the permission "iam.serviceAccounts.getOpenIdToken" on itself. You need to assign at least the role "Service Account OpenID Connect Identity Token Creator" in the service account permissions to the service account itself, to make it work.
    The error message is therefore very misleading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions