javagoogle-vision

Google Vision API with Multi-regional support: gives StatusRuntimeException: UNAUTHENTICATED when using with custom endpoint


Getting the StatusRuntimeException: UNAUTHENTICATED when using with custom endpoint as per the following guide: Google Vision API - Multi-regional support

But all works fine when using default endpoint. See the code sample below:

Credentials credentials = ServiceAccountCredentials.fromStream(new FileInputStream(credPath));

// Works fine
ImageAnnotatorSettings settings = ImageAnnotatorSettings.newBuilder().setCredentialsProvider(FixedCredentialsProvider.create(credentials)).build();

// Works fine as well
ImageAnnotatorSettings settings = ImageAnnotatorSettings.newBuilder().setCredentialsProvider(FixedCredentialsProvider.create(credentials)).setEndpoint("vision.googleapis.com:443").build();

// Doesn't work - throws exception:
ImageAnnotatorSettings settings = ImageAnnotatorSettings.newBuilder().setCredentialsProvider(FixedCredentialsProvider.create(credentials)).setEndpoint("us-vision.googleapis.com:443").build();

visionClient = ImageAnnotatorClient.create(settings);

Exception is the following:

com.google.api.gax.rpc.UnauthenticatedException: io.grpc.StatusRuntimeException: UNAUTHENTICATED: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
    at com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:73)
    at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:72)
    at com.google.api.gax.grpc.GrpcApiExceptionFactory.create(GrpcApiExceptionFactory.java:60)
    at com.google.api.gax.grpc.GrpcExceptionCallable$ExceptionTransformingFuture.onFailure(GrpcExceptionCallable.java:97)
    at com.google.api.core.ApiFutures$1.onFailure(ApiFutures.java:68)
    at com.google.common.util.concurrent.Futures$CallbackListener.run(Futures.java:1074)
    at com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:30)
    at com.google.common.util.concurrent.AbstractFuture.executeListener(AbstractFuture.java:1213)
    at com.google.common.util.concurrent.AbstractFuture.complete(AbstractFuture.java:983)
    at com.google.common.util.concurrent.AbstractFuture.setException(AbstractFuture.java:771)
    at io.grpc.stub.ClientCalls$GrpcFuture.setException(ClientCalls.java:563)
    at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:533)
    at io.grpc.internal.DelayedClientCall$DelayedListener$3.run(DelayedClientCall.java:463)
    at io.grpc.internal.DelayedClientCall$DelayedListener.delayOrExecute(DelayedClientCall.java:427)
    at io.grpc.internal.DelayedClientCall$DelayedListener.onClose(DelayedClientCall.java:460)
    at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:557)
    at io.grpc.internal.ClientCallImpl.access$300(ClientCallImpl.java:69)
    at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:738)
    at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:717)
    at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
    at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:829)
    Suppressed: com.google.api.gax.rpc.AsyncTaskException: Asynchronous task failed
        at com.google.api.gax.rpc.ApiExceptions.callAndTranslateApiException(ApiExceptions.java:57)
        at com.google.api.gax.rpc.UnaryCallable.call(UnaryCallable.java:112)
        at com.google.cloud.vision.v1.ImageAnnotatorClient.batchAnnotateImages(ImageAnnotatorClient.java:203)
        at com.google.cloud.vision.v1.ImageAnnotatorClient.batchAnnotateImages(ImageAnnotatorClient.java:179)
        ...
        at com.sun.ejb.containers.EjbAsyncTask.call(EjbAsyncTask.java:101)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        ... 3 more
Caused by: io.grpc.StatusRuntimeException: UNAUTHENTICATED: Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
    at io.grpc.Status.asRuntimeException(Status.java:535)
    ... 13 more

Any thoughts how to fix that? Thanks!


Solution

  • Just in case it might help someone, I had this issue: Google DocumentAI Java example fails with io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Request contains an invalid argument THEN the same issue described here that I solved this way:

    export GOOGLE_APPLICATION_CREDENTIALS=/path/to/my/key.json
    
    .setCredentialsProvider(FixedCredentialsProvider.create(credentials))
    
    .setCredentials(ServiceAccountCredentials.fromStream(new FileInputStream("/path/to/my/key.json")))
    
    Credentials credentials = 
                ServiceAccountCredentials
                  .fromStream(credentialStream)
                  .createScoped("https://www.googleapis.com/auth/cloud-platform")
    

    And it worked ! It could also work if you edit the key.json file to add the scope in the array, I haven't tested it.

    Both issue came from a lack of documentation in the Java libraries, so If someone from Google read this answer, please complete the documentation.