Repository navigation
Description
Operating System
Not OS-specific. The defect is in SDK source. Observed in a Chromium browser.
Environment (if applicable)
Browser-based JS app (also applies to Node >= 22, which is where the Live WebSocket handler runs). Not browser- or runtime-specific; the missing-token code path is the same everywhere.
Firebase SDK Version
firebase (umbrella) 12.14.0 / @firebase/ai 2.13.0
Firebase SDK Product(s)
AI
Project Tooling
Next.js + TypeScript web app. Firebase AI Logic (@firebase/ai) with the Vertex AI backend, App Check enforced via reCAPTCHA Enterprise.
Detailed Problem Description
What you were trying to achieve
Open a Live API session with getLiveGenerativeModel(...).connect() on the Vertex AI backend, with App Check enforced on the Firebase AI Logic API (firebasevertexai.googleapis.com). App Check is initialized per the official reCAPTCHA Enterprise web guide, with isTokenAutoRefreshEnabled: true. HTTPS calls under the same enforcement are confirmed attested and succeed, so the token resolves correctly; only the Live path is affected.
What actually happened
The Live WebSocket session never establishes. The server closes the connection during the setup handshake and connect() rejects. On the same AI instance, with the same App Check setup, the HTTPS methods (generateContent, generateContentStream, countTokens) all work fine. Only the Live (connect()) path fails, and it fails the same way in every region tried (europe-west1, europe-west4, europe-southwest1).
Error messages / unexpected behavior observed
- The server closes the socket with reason:
Firebase App Check token is invalid. connect()then rejects with:AI: Server connection handshake failed. The server did not respond with a setupComplete message. (AI/response-error)- The surprising part: inspecting the actual WebSocket handshake, the App Check token doesn't appear to be sent at all. The
wss://URL carries only?key=...with no App Check token in the query string, and the firstsetupframe contains only the model + generation config. So the server reports "invalid," but from what I can see the token is absent rather than malformed. - This looks like the same close reason reported for Android in firebase-android-sdk#8060.
Relevant log snippets / console output
@firebase/vertexai: WebSocket connection closed by server. Reason: 'Firebase App Check token is invalid.'
@firebase/vertexai: WebSocket connection closed by the server with reason: Firebase App Check token is invalid.
FirebaseError: AI: Server connection handshake failed. The server did not respond with a setupComplete message. (AI/response-error)
at lu._connectSession (...)
at async ld.connect (...)
Observed handshake URL:
wss://firebasevertexai.googleapis.com/ws/google.firebase.vertexai.v1beta.LlmBidiService/BidiGenerateContent/locations/<LOCATION>?key=<API_KEY>
Possible cause (I might be missing context)
I poked around the source to understand it. The Live path builds its URL in WebSocketUrl (packages/ai/src/requests/request.ts) and seems to set only the key query param, whereas the HTTPS path's getHeaders in the same file attaches X-Firebase-AppCheck from getAppCheckToken(). I couldn't find a getAppCheckToken() call on the Live path, which would line up with the token never being sent. Since a browser/Node WebSocket can't set request headers, I'd guess the token has to travel via the URL or the setup message instead, but I don't know what the bidi endpoint actually expects.
Question for maintainers
Is the intended fix to resolve the App Check token before connecting and pass it on the WebSocket URL or in the setup message? Or is the Live path structured this way deliberately for a reason I'm not seeing? Happy to test a patch if that's useful.
Steps and code to reproduce issue
- In the Firebase console, enable App Check enforcement for the Firebase AI Logic API (
firebasevertexai.googleapis.com). - Initialize App Check, then call the Live API alongside an HTTPS call. The HTTPS call succeeds and the Live call fails with the same setup:
import { initializeApp } from 'firebase/app';
import { initializeAppCheck, ReCaptchaEnterpriseProvider } from 'firebase/app-check';
import {
getAI,
getGenerativeModel,
getLiveGenerativeModel,
VertexAIBackend,
ResponseModality
} from 'firebase/ai';
const app = initializeApp({ /* firebaseConfig */ });
initializeAppCheck(app, {
provider: new ReCaptchaEnterpriseProvider('<RECAPTCHA_ENTERPRISE_SITE_KEY>'),
isTokenAutoRefreshEnabled: true
});
// Any location reproduces this; the bug is region-independent.
const ai = getAI(app, { backend: new VertexAIBackend('us-central1') });
// HTTPS path: SUCCEEDS (App Check token sent via the X-Firebase-AppCheck header)
const model = getGenerativeModel(ai, { model: 'gemini-2.5-flash' });
await model.generateContent('ping'); // OK
// Live path: FAILS (no App Check token on the WebSocket handshake)
const liveModel = getLiveGenerativeModel(ai, {
model: 'gemini-live-2.5-flash-native-audio',
generationConfig: { responseModalities: [ResponseModality.AUDIO] }
});
const session = await liveModel.connect();
// connect() rejects; the server closes the socket with
// "Firebase App Check token is invalid."- Observe that
connect()rejects whilegenerateContent()on the same instance succeeds. - To check whether the token is absent rather than malformed: in DevTools, open the Network panel, filter to WS, and inspect the
BidiGenerateContentconnection. The request URL shows only?key=<API_KEY>, with no App Check token; the first sent frame (setup) contains only the model + generation config. - As a further check that App Check is the cause: temporarily disable App Check enforcement for the AI Logic API and re-run. The Live path then connects.
Activity
hsubox76 commentedon May 29, 2026
This is a known issue due to the fact that, as you mentioned, Websocket can't send headers from the browser. (It actually can in Node I believe.) In order to fix this, we (Firebase) need to find another way to send the App Check token, and modify the backend to accept the new way, which is a problem we are working on.
phanquanghung commentedon Jun 2, 2026
Thanks for the quick reply.
Quick question for the interim: since enforcement is all-or-nothing right now, would it be feasible to exempt just the web Live path? The text/image paths are the most exposed to client abuse (what App Check is for), but right now we can't enforce there without breaking web Live.
artem-sherbachuk commentedon Oct 9, 2026
We are also affected with
[email protected]/@firebase/[email protected], usingGoogleAIBackend(Gemini Developer API), so this is not limited toVertexAIBackend.gemini-3.1-flash-live-preview.generateContentrequest returning HTTP 200 withX-Firebase-AppCheckpresent. Live.connect()closes with code 1008, reasonFirebase App Check token is invalid., withoutsetupComplete.WebSocketUrladds only the API-key query parameter, and the Live connection path does not acquire/send an App Check token. OurgetAIconfiguration includesuseLimitedUseAppCheckTokens: true; that does not add a token to Live.Workaround verified: after setting both Basic and Replay enforcement to Monitoring, an immediate retry still failed. A fresh Chrome session started 15 minutes 30 seconds after the setting change received
setupCompleteand the actual model greeting. No SDK patch, proxy, or direct Gemini connection was used. This verifies connection and initial output, not a complete conversation.The Firebase documentation now says App Check enforcement becomes mandatory on November 2, 2026 and cannot be disabled afterwards. Is there a supported browser Live fix or migration path planned before that deadline? Is a Live-only exception possible so HTTPS calls can remain protected?
ibdavid7 commentedon Oct 10, 2026
We're affected too, and the mandatory enforcement on 2026-11-02 (which the AI Logic FAQ says cannot be turned off) leaves web Live with no way to keep working inside Firebase.
Setup: Next.js web app,
@firebase/ai2.14.0,VertexAIBackend('us-central1'),gemini-live-2.5-flash-native-audio, App Check viaReCaptchaEnterpriseProvider.Observed in production on 2026-10-07, with AI Logic enforcement temporarily ON:
getToken()returned a valid App Check token, so the provider setup is fine.connect()failed on 8 of 8 attempts with that valid token:Server connection handshake failed… did not respond with a setupComplete message.?key=. No App Check token is in the URL or thesetupframe.The latest release doesn't change this. In
@firebase/ai3.0.0 ([email protected], 2026-10-07),WebSocketUrl.toString()still sets onlykey, andLiveSession._connectSession()never callsgetAppCheckToken(). Upgrading is not a workaround.Two questions:
hsubox76 commentedon Oct 28, 2026
Sorry for the delay in getting back to you, I know the enforcement deadline is coming up soon. Unfortunately I don't have very encouraging answers:
The only workaround I can suggest for using Gemini Live API capabilities in a web app, with abuse protection, is to stop using the Live API from the Firebase AI Logic Web SDK until it can use App Check and instead use the Gemini SDKs directly (Python, JS, or the REST API on the server, and JS on the client) and use their ephemeral token workflow: https://ai.google.dev/gemini-api/docs/live-api/ephemeral-tokens . This requires a server layer that runs a Gemini server-side SDK (or calls the REST endpoint). If you don't have a server, you can use a cloud function for that part of the flow. The cloud function or server will act as an intermediate layer securely gating access - see that link for more details.
Note that this ephemeral token capability isn't available for Agent Platform API, only the Gemini Developer API.
tzuhaohuang commentedon Oct 30, 2026
I've been affected too and I've delayed enforcement to Jan 2027. Just want to make sure I still have time to update my app to the workaround solution. Thanks
CarlTonsgard commentedon Nov 2, 2026
We’re affected too: web Live on the Agent Platform backend (eu), firebase 12.19.0.
The FAQ says automatic enforcement can be delayed, and on our dev project that worked, but on our production project the edit control next to “Enforces Nov 2, 2026” never appears.
We’re Owner on the project and re-ran the AI Logic App Check setup, and it still isn’t there. We’ve filed a support case.
Is there another way to delay enforcement on production before it starts?