early-window-29567
02/26/2026, 1:50 PMtall-airline-16756
02/26/2026, 1:50 PMtall-airline-16756
02/26/2026, 1:51 PM{ error: 'invalid token' } from [api/room/create], plus the Firestore CORS and cross-origin frame errors in the console.
Quick summary of likely causes
• The JWT token used in production is invalid because the API secret, token generation, or claims differ from your local setup.
• Room name in the token grant may not match the room you request.
• Production environment variables (LIVEKIT_API_KEY, LIVEKIT_API_SECRET, LIVEKIT_URL) may be missing, truncated, or incorrect.
• CORS issues (Firestore) and iframe origin mismatch are separate issues but can indicate broader deployment misconfiguration.
Please try these checks in order — they’re the fastest way to find the root cause.
1) Verify production environment variables
• Confirm that LIVEKIT_API_KEY, LIVEKIT_API_SECRET, and LIVEKIT_URL in production match the values you use locally.
• Ensure the secret isn’t truncated, URL-encoded, or contains stray whitespace/newlines.
• If you recently updated env vars, redeploy so the new values are in effect.
2) Confirm token is generated server-side and correctly shaped
• Tokens must be created on the server (using the server SDK) with your API secret. If tokens are generated client-side, they’ll be invalid.
• Temporarily log the generated token in production (only in a safe dev mode), copy it, and decode it at https://jwt.io:
◦ Check the issuer (iss) equals your API key.
◦ Ensure the grant contains roomJoin: true and the room claim exactly matches the room name (e.g., 5SJjvZarenoXJA9pYsmv).
• If you can, generate a token locally with the same API key/secret and use that token in production to test. If that works, production token generation is the issue.
3) Check your token generation code (common pitfalls)
• Use the server SDK to create AccessToken and add the room grant (don’t use client SDK on server).
• Make sure you’re not URL-encoding or altering the room name or token string when sending it to the client or to LiveKit.
• Ensure the grant includes required permissions (canPublish/canSubscribe if needed).
4) Verify LIVEKIT_URL and where you call LiveKit
• Ensure LIVEKIT_URL in production points to the correct LiveKit host (your LiveKit Cloud host or your self-hosted domain).
• A URL mismatch can cause token validation failure.
5) Short debug sequence you can run now
1. Generate a token locally with your known-good local env and decode it at jwt.io to inspect claims.
2. Deploy that same token into production and attempt your create call. If it works, the issue is production token generation or secrets.
3. If it fails, double-check LIVEKIT_URL and that the client is actually sending the token you think it is (inspect network call headers/body).
6) Addressing the console errors you posted
• The Firestore "Fetch API cannot load ... due to access control checks" is a Firestore CORS issue — unrelated to LiveKit tokens. Fix it by ensuring your frontend origin is allowed or use server-side API routes for Firestore access.
• "Blocked a frame with origin ... from accessing a frame with origin https://kylian-5b8d1.firebaseapp.com" is a browser same-origin security enforcement — usually harmless for LiveKit unless you rely on cross-frame access.
• The 500 on create is the LiveKit token problem; fix tokens first, then re-check these console messages.
If you want, I can guide you through specific checks. Can you share:
• Whether you generate tokens server-side or client-side in production?
• The exact code snippet you use to create tokens (remove secrets before sharing)?
• How you're storing/setting env vars in production (Vercel/Netlify/Docker/K8s/etc.)?
With that I’ll give tailored steps to find the mismatch and get production back working.
Sources: server-sdk-js | livekit/livekit_composite | DeepWiki | Server-side | livekit/livekit_composite | DeepWiki