Genace

API keys are not supported by this API. Expected OAuth2 access token — Veo operation polling 401 (Gemini API, Vertex)

HTTP 401 UNAUTHENTICATED Do not retry as-is

The exact error

API keys are not supported by this API. Expected OAuth2 access token or other authentication credentials that assert a principal.

What it means

The endpoint that received your call accepts only OAuth2 credentials, meaning an access token for a user or service account, and you sent an API key. The key itself may be perfectly valid. The problem is that this endpoint does not take keys at all. In Veo workflows this tends to appear on the second step: the generate call succeeds and returns an operation, and then polling that operation fails.

The main public report is python-genai issue #2233, which is still open. The reporter used google-genai 1.20.0 or later with veo-3.1-fast-generate-preview, in an environment where GOOGLE_GENAI_USE_VERTEXAI=True was set for other Gemini services. They found that no single client configuration completed the whole flow:

  • A Vertex client (vertexai=True) failed on generate_videos with an SDK message saying the method is only supported in the Gemini Developer client.
  • An API-key client ran generate_videos successfully, but operations.get failed with this 401.
  • A client created with only project and location, using Application Default Credentials (ADC), worked for both steps, but only while the environment variable was unset.

A responder on the issue said they reproduced it and would file a bug internally. The reporter’s workaround was to remove the environment variable temporarily while creating the client. They warned this is fragile and not thread-safe.

Merged variant: Request had insufficient authentication scopes. This is a 403 PERMISSION_DENIED with reason ACCESS_TOKEN_SCOPE_INSUFFICIENT. It is the OAuth-side version of the same mismatch: you sent a token, but it lacks the right scopes. In Google Developer forums thread 269125, a developer started veo-3.0-generate-001:predictLongRunning on the Gemini API with a service-account token and got an operation ID back. Polling it failed with this 403, and the error metadata named google.longrunning.Operations.GetOperation on generativelanguage.googleapis.com. They had tried the cloud-platform and generative-language scopes. The thread has no answer.

How to confirm it’s this

  • The POST that starts generation succeeded and returned an operation name. The GET that polls it returns 401 UNAUTHENTICATED with this message, or 403 with ACCESS_TOKEN_SCOPE_INSUFFICIENT.
  • Print which host each call goes to. generativelanguage.googleapis.com is the Gemini API. aiplatform.googleapis.com is Vertex AI, now called Gemini Enterprise Agent Platform.
  • Check the environment of the process that polls, especially GOOGLE_GENAI_USE_VERTEXAI and GOOGLE_APPLICATION_CREDENTIALS. A worker or scheduled job can have different settings from the process that started the job.
  • Check whether the poll uses the same client object, and therefore the same credentials, as the generate call.

Fix

  1. Poll with the client that created the operation. Google’s Veo page polls with client.operations.get(operation) on the same client in Python. Its REST example polls ${BASE_URL}/${operation_name} on the Gemini API with the same x-goog-api-key header used to start the job.
  2. Keep the backend selection consistent. If a global GOOGLE_GENAI_USE_VERTEXAI setting pulls part of your video flow onto Vertex, give the video client its own explicit configuration. Issue #2233 reports that a project plus location client with ADC completed both steps when the variable was not set. The issue is still open, so check it for an SDK fix before relying on the environment-variable workaround.
  3. If you use OAuth against the Gemini API, follow Google’s OAuth quickstart for the Gemini API. It requests the cloud-platform and generative-language.retriever scopes and sends an x-goog-user-project header with the project ID. Whether these scopes also fix the polling failure in thread 269125 has not been confirmed.

Retry or not

No. This is a credentials mismatch, so the same call with the same credentials fails the same way. The generation itself is not lost. In issue #2233 and thread 269125, the generate step succeeded and returned an operation, so fix the poller’s credentials and poll that operation again instead of starting a new generation. Google’s Veo page says finished videos stay on the server for 2 days, which gives you a window to recover. An agent should mark this as a non-retryable auth error and escalate rather than resubmitting the job.

When it’s not this

  • An invalid or missing key. Google’s API errors page lists an authentication code (401) for a missing, invalid or expired key. That is a bad key. This error is a valid key sent to an endpoint that does not accept keys.
  • A 403 about project 542708778979 comes from downloading the finished video without credentials, which happens after polling succeeds.
  • The SDK’s “only supported in the Gemini Developer client” message is the other half of the mismatch described in issue #2233: the Vertex client refusing generate_videos instead of the key client failing to poll.

Error text last verified against the sources below on .

Where these facts come from