Next.js dev server fails with "Blocked cross-origin request" in a proxied environment (Firebase Studio / Cloud Workstations)

Hello,

I’m running a Next.js application within a managed development environment (Firebase Studio, which uses Google Cloud Workstations) and I’m stuck in a loop with a cross-origin error. The Next.js dev server starts, but the browser is unable to load Next.js resources (like scripts and HMR) because the requests are being blocked.

The error in the server logs is consistently: Error: ⚠ Blocked cross-origin request from <URL> to /_next/* resource. To allow this, configure "allowedDevOrigins" in next.config

The URL in the error message is dynamic, often looking something like 6000-firebase-studio-....cloudworkstations.dev or 9000-firebase-studio-....cloudworkstations.dev.

What I’ve tried:

I have repeatedly modified my next.config.ts to include these URLs in the allowedDevOrigins array. Here is my current next.config.ts:

import type {NextConfig} from 'next';

const nextConfig: NextConfig = {
  /* config options here */
  typescript: {
    ignoreBuildErrors: true,
  },
  eslint: {
    ignoreDuringBuilds: true,
  },
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'placehold.co',
        port: '',
        pathname: '/**',
      },
      {
        protocol: 'https',
        hostname: 'images.unsplash.com',
        port: '',
        pathname: '/**',
      },
      {
        protocol: 'https',
        hostname: 'picsum.photos',
      },
    ],
  },
  allowedDevOrigins: [
    'https://*.cluster-hllxpfasbba62ri4b2ygaupuxu.cloudworkstations.dev',
    'https://6000-firebase-studio-1759340049650.cluster-hllxpfasbba62ri4b2ygaupuxu.cloudworkstations.dev',
    'https://9000-firebase-studio-1759340049650.cluster-hllxpfasbba62ri4b2ygaupuxu.cloudworkstations.dev',
    'https://9002-firebase-studio-1759340049650.cluster-hllxpfasbba62ri4b2ygaupuxu.cloudworkstations.dev',
  ],
};

export default nextConfig;

Despite adding a wildcard ('https://*.cluster-hllxpfasbba62ri4b2ygaupuxu.cloudworkstations.dev') and specific URLs from the logs, the issue persists after every server restart. It feels like the configuration is not being respected or is being overwritten.

Environment Details:

  • Next.js version: 15.3.3

  • Dev command: next dev --turbopack -p 9002

  • Environment: Firebase Studio / Google Cloud Workstations (containerized, proxied)

Has anyone encountered this in a similar proxied or containerized dev environment? Is there a known issue with allowedDevOrigins and Turbopack, or a different configuration required for this kind of setup?

1 Like

I’ve seen this happen in proxied dev environments (like Firebase Studio Cloud Workstations, Gitpod, etc.), especially when Next.js tries to enforce allowedDevOrigins and your dev server is sitting behind a layer of reverse proxy. A few angles to try:Make sure the full proxied URL is whitelisted, not just localhost.

1. Check your next.config.js (dev server CORS)

const nextConfig = {
experimental: {
// add the proxied origin explicitly
allowedDevOrigins: [
http://localhost:3000”,
“https://.cloudworkstations.dev”
],
},
};
module.exports = nextConfig;


2. Proxy Headers / Upgrade

Some workstation proxies strip or rewrite headers.

  • Look for Origin, Host, or Upgrade (for WebSockets / hot reload) mismatches.

  • If you see “blocked cross-origin request” in logs, try forcing the dev server to bind 0.0.0.0 instead of localhost:

next dev -H 0.0.0.0


3. Fallback Mode: Disable Strict Check

If this is just for local development, you can disable strict origin checking as a stopgap:

headers: async () => [
  {
    source: "/(.*)",
    headers: [
      { key: "Access-Control-Allow-Origin", value: "*" }
    ]
  }
]

:warning: Not for production — just to verify if the proxy is the blocker.


4. Asynchronous Load Screen Pattern

One trick we’ve used in constrained environments is introducing a loading screen / async gateway (instead of direct API hits during dev). This avoids live CORS altogether during iteration and defers auth + routing until after proxy negotiation.


:vertical_traffic_light: TL;DR

  • Explicitly add your workstation proxy URL to allowedDevOrigins.

  • Run dev server on 0.0.0.0.

  • If still stuck, test with Access-Control-Allow-Origin: * to confirm the proxy is the culprit.

  • Once verified, tighten it back down for safety.

If you want, I can also share a kit for debugging proxied environments — lightweight ANSI signals you can drop into your dev console logs to quickly see whether the proxy or Next.js is dropping the ball.

Did you add your domains as ‘Authorised domains’ to Firebase console? (Authentication > Authorised domains). You probably have localhost and a couple of other base URLs for your app listed, but may need to add your port urls too: 6000yourappurl, 9000yourappurl.

And have you got 3rd party cookies enabled in your browser? Firebase renders an iframe from one domain (a subdomain of cloudworkstations.dev) on another domain (studio.firebase.google.com), and 3P cookies enable secure cross-origin communication.

Crie um tunnel com o CloudFlared pelo proprio console e utilize o link do Tunnel

Hey there,

I feel your pain on this. I ran into this exact kind of frustrating cross-origin loop while using a proxied dev environment (ngrok in our case, but the principle is the same as Firebase Studio/Cloud Workstations). The allowedDevOrigins config just wasn’t reliable for us.

The solution that has been 100% stable for us was to stop trying to fight the cross-origin battle in the browser and instead let the Next.js server handle it. We did this by creating our own simple API proxy using a Next.js Route Handler.

The Concept

The idea is to have your frontend application only make same-origin requests to a special endpoint within your Next.js app (e.g., /api-proxy). This route handler then takes the request, forwards it to your actual backend API, and streams the response back to your browser.

From the browser’s perspective, it’s just talking to the Next.js server, so CORS issues completely disappear.

How We Built It

It’s a two-step process:

1. Create the Proxy Route Handler

We created a catch-all route handler at src/app/api-proxy/[...path]/route.ts. This file intercepts any request made to /api-proxy/*.

Here’s the code for our handler:

TypeScript

// src/app/api-proxy/[...path]/route.ts
import { NextRequest, NextResponse } from 'next/server';

async function handler(req: NextRequest) {
  // 1. Get your actual backend URL from an environment variable
  const backendUrl = process.env.NEXT_PUBLIC_BACKEND_API_URL;
  if (!backendUrl) {
    return new NextResponse('Backend API URL is not configured.', { status: 500 });
  }

  // 2. Reconstruct the path and search params for the backend
  const requestedPath = req.nextUrl.pathname.replace(/^\/api-proxy/, '');
  const targetUrl = `${backendUrl}${requestedPath}${req.nextUrl.search}`;

  // 3. Clone headers, fixing the 'host' to avoid issues
  const headers = new Headers(req.headers);
  headers.set('host', new URL(targetUrl).host);
  headers.set('ngrok-skip-browser-warning', 'true'); // Specific to ngrok, but useful for other proxies
  headers.set('Connection', 'keep-alive');

  // 4. Await the body properly for non-GET requests
  const body = req.method !== 'GET' && req.method !== 'HEAD' ? await req.blob() : undefined;

  try {
    // 5. Make the server-to-server request and stream the response back
    const response = await fetch(targetUrl, {
      method: req.method,
      headers: headers,
      body: body,
      redirect: 'follow'
    });
    
    return response;

  } catch (error) {
    console.error('API proxy error:', error);
    return new NextResponse('Proxy request failed.', { status: 502 });
  }
}

export { handler as GET, handler as POST, handler as PUT, handler as PATCH, handler as DELETE };

2. Point Your Frontend Client to the Proxy

Next, we just had to make sure our frontend code called our new proxy instead of the external API directly. We did this by setting our base URL environment variable.

In .env.local:

NEXT_PUBLIC_API_BASE_URL=/api-proxy

Now, any fetch call in our app that looks like fetch('/api-proxy/prompts') gets seamlessly routed to our real backend by the Next.js server.

While your issue is with Next.js’s internal /_next resources and not a separate API, I wanted to share this pattern because it’s a powerful way to solve these kinds of problems in complex, proxied environments when the standard configuration options don’t seem to work.

Hope this helps you or someone else who gets stuck!

1 Like

Thank you all for chipping in, I explored all the solutions offered here, and more.
I just gave up dealing with Firebase, it’s a time trap/loophole…
Maybe in the future, but not at the moment… It’s just making both of us miserable, I don’t know who is more so! Well, at least I’m not self deprecating! :smile:

1 Like

Subject: Stable Fix for Cross-Origin + Firebase Studio Loops

Hey @cemster

First, I would like to say that this fix I am offering you should stabilize your environment and get you going in the right direction. Next, I would like to offer you a tip I discovered when learning to work more efficiently with this application-so much so that this advice comes straight from my own DevOps Manual, which if you didn’t have to start this project you should take the time to create. In it will be the Tree of your project and each file. Next will be a Sanity Checklist for each of those folders and files that you have developed from the Documentation. Dev Logs and Git Repository and instructions for how you address errors.

Something you can consider is using Figma to draft out a new project for you using all the design and dev notes you have leading up to the project breaking. This will give you a clean deployable project that you can use to overwrite your current project.

Next, this response came from the Gemini AI Assist from my current project. This is how you can train the AI to help you not only with your project, but it can also resolve Errors in other Firebase Studio projects. Now as to both responses you are getting the error due to the applications Default Design. You are introducing something in your design that is not allowed, get your design compatible with the applications Rules and you should Develop Long and Prosper:partying_face:

Chad’s solution is actually spot-on for anyone running into the CORS / auth redirect pain inside proxied environments like Firebase Studio, ngrok, or local tunnels.

Firebase’s built-in dev tools sometimes spawn temporary origins, which causes Firebase Auth or CORS validation to fail intermittently — even when you’ve added the right origins.

The cleanest fix we’ve seen in production is to route all client API calls through your own app, using a simple proxy endpoint like Chad’s /api-proxy/[...path].

That way:

  • Your browser only ever talks to your app’s own origin :white_check_mark:

  • The Next.js server handles the real backend call :white_check_mark:

  • CORS issues completely vanish :white_check_mark:

Here’s a quick snapshot of that concept:

// src/app/api-proxy/[...path]/route.ts
import { NextRequest, NextResponse } from 'next/server';

export async function handler(req: NextRequest) {
  const backendUrl = process.env.NEXT_PUBLIC_BACKEND_API_URL!;
  const requestedPath = req.nextUrl.pathname.replace(/^\/api-proxy/, '');
  const targetUrl = `${backendUrl}${requestedPath}${req.nextUrl.search}`;

  const response = await fetch(targetUrl, {
    method: req.method,
    headers: req.headers,
    body: req.method !== 'GET' ? await req.blob() : undefined,
  });
  return response;
}
export { handler as GET, handler as POST };

Then just set:

NEXT_PUBLIC_API_BASE_URL=/api-proxy

It’s a one-time setup that eliminates the “CORS time trap” completely.

For anyone feeling stuck or burned out — totally valid. Firebase’s integrations can feel like a maze, especially when multiple layers (Auth, Hosting, Studio) overlap.

But the proxy route pattern is a solid exit ramp — you regain control of your routing and don’t have to constantly chase origin settings.

Let me know if this moves you forward or if you would like help with training your AI Bot