API keys are not supported by this API. Expected OAuth2 access token — Veo operation polling 401 (Gemini API, Vertex)
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 ongenerate_videoswith an SDK message saying the method is only supported in the Gemini Developer client. - An API-key client ran
generate_videossuccessfully, butoperations.getfailed with this 401. - A client created with only
projectandlocation, 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
UNAUTHENTICATEDwith this message, or 403 withACCESS_TOKEN_SCOPE_INSUFFICIENT. - Print which host each call goes to.
generativelanguage.googleapis.comis the Gemini API.aiplatform.googleapis.comis Vertex AI, now called Gemini Enterprise Agent Platform. - Check the environment of the process that polls, especially
GOOGLE_GENAI_USE_VERTEXAIandGOOGLE_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
- 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 samex-goog-api-keyheader used to start the job. - Keep the backend selection consistent. If a global
GOOGLE_GENAI_USE_VERTEXAIsetting pulls part of your video flow onto Vertex, give the video client its own explicit configuration. Issue #2233 reports that aprojectpluslocationclient 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. - If you use OAuth against the Gemini API, follow Google’s OAuth quickstart for the Gemini API. It requests the
cloud-platformandgenerative-language.retrieverscopes and sends anx-goog-user-projectheader 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
authenticationcode (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_videosinstead of the key client failing to poll.
Related errors
- Generative Language API has not been used in project 542708778979
- Model not found for API version v1beta
- Veo 3.1 quota exceeded
- Veo support codes
- 429 RESOURCE_EXHAUSTED
Error text last verified against the sources below on .