Next.js app shows "Ready" on 'npm run dev' but returns 404 Not Found in cloud dev environment

Hello everyone,

I’m experiencing a strange issue in my cloud-based development environment and I’m stuck.

Context:

  • Stack: Next.js 14.2.4

  • Environment: A cloud-based development environment (similar to Google Cloud Shell Editor or IDX).

  • Run command: npm run dev

The Problem: When I run npm run dev, the application seems to start up perfectly. The terminal shows that the server is ready and the routes are compiling correctly. However, when I try to access the application’s URL, the browser displays a 404 Not Found error.

This issue appeared suddenly, without me making any significant changes to routing or the Next.js server configuration.

Evidence (Terminal Log): I have confirmed that the Next.js server is running. This is the log I’m getting in the terminal:

> bettrackpro-app@0.1.0 dev
> next dev

  ▲ Next.js 14.2.4
  - Local:        http://localhost:3000
  - Environments: .env.local, .env

 ✓ Starting...
 ✓ Ready in 7.5s
 ○ Compiling /_not-found ...
 ✓ Compiled /_not-found in 19.1s (891 modules)
 i18next: languageChanged es
 ... (rest of i18next log) ...
 GET / 404 in 20402ms
 ○ Compiling /src/middleware ...
 ✓ Compiled /src/middleware in 874ms (118 modules)

The key lines are:

  • ✓ Ready in 7.5s: Indicates that the Next.js server started successfully.

  • GET / 404 in 20402ms: Shows that a request to the root (/) was received, but the result was a 404.

Diagnostic Steps I’ve Already Taken:

  1. I ran npm run build, and it completed successfully (Compiled successfully), which confirms there are no syntax or build errors in the Next.js code.

  2. My src/middleware.ts file is very simple and only contains NextResponse.next(), so it shouldn’t be interfering.

  3. The problem seems to be with the routing of the development environment itself, which is not correctly forwarding the request to the Next.js application running on localhost:3000.

My Question: Has anyone experienced a similar issue in a cloud development environment where the reverse proxy or routing layer stops working and returns a 404, even though the underlying application is running correctly?

Is there any way to debug or “refresh” this routing layer of the environment?

Any help or ideas would be greatly appreciated. Thanks

3 Likes

Estou enfrentando o mesmo problema, já faz uma semana.

I’ve been getting a similar 404 on my app in the Firebase Studio development environment for the last day. Gemini thought it was due to a routing error, but then we replaced the code with a Hello World app and still received the 404.

When I select “Hard Restart” from the drop down arrow, the server log is displayed for 2 seconds, then a progress bar is displayed, and finally several seconds later the “404 | This page could not be found.” appears. I did a screen recording and then paused the recording and took the screen shot shown below. I hope this helps.

Same too! I thought I tanked my app that’s been weeks in the making. Just loads a 404 now and I don’t want to test publishing incase it wipes out my live site www.socialsays.co.uk

I’ve compared all the functional files with another working app and I’ve had gemini and chatgpt run through the files and I makes no difference.

The only progress I’ve made in trouble shooting is when I package the app the /out folder never pulls through the files other than a 404 page.

Fixed mine with this post… 404 Error :- This Page could not be loaded - #8 by TimST

Hope you get yours sorted too.

1 Like

Try running npm run build. the copy and paste the error into the prototyper. be sure to state in your prompt, “Explain. Don’t make changes”, so it doesn’t go off making changes right away.

Thanks! That worked for me too.

1 Like

Ask the AI to run the command npm run dev.

It will make a button for you so send the console command.

Once all the loading and errors messages are done loading press crt + c stop the server.

This will trigger to the AI to read through the logs.

Bonjour à tous, j’ai moi-même vécu cette galère après avoir été confronté à un “hit-snag” qui m’a conduit à installer .aiexclude , mais cela ne s’est pas passé comme prévu, bref … regardez du coté du fichier dev.nix . Copiez-collez du code que je mets ici, vérifié bien le chemin d’accès de votre page initiale, validez la reconstruction et vous aurez peut-être corrigé le problème. En tout cas, je vous le souhaite. Cordialement,

dev.nix (modèle générique, corrigé)

Super idée :+1: Je t’ai préparé une version générique et “propre” de ton dev.nix, plus portable, avec des marqueurs faciles à remplacer. Juste en dessous, tu as une notice claire en français qui explique quoi modifier et où.


dev.nix (modèle générique, corrigé)

{ pkgs, ... }:

{
  # Version du canal Nixpkgs (garde "stable-24.11" si ton workspace le supporte)
  channel = "stable-24.11";

  # Outils disponibles dans l'environnement
  packages = with pkgs; [
    nodejs_20        # → passe à nodejs_22 si ton projet l'exige
    zulu             # JDK (optionnel, utile pour certains outils)
    git              # pratique pour git hooks/CLI
  ];

  # Variables d'environnement communes (optionnel)
  # env = { NODE_ENV = "development"; };

  # (Optionnel) Emulateurs Firebase auto-configurés
  services.firebase.emulators = {
    detect = true;                              # lit firebase.json si présent
    projectId = "<TON_PROJECT_ID_FIREBASE>";    # ← REMPLACER
    services  = [ "auth" "firestore" ];         # ← AJUSTER (ex: "functions" "storage" …)
    # Exemple si tu veux des ports fixes :
    # ports = { auth = 9099; firestore = 8080; };
  };

  # Intégrations pour l’IDE (ex: Google/Project IDX)
  idx = {
    workspace = {
      onCreate = {
        # Ouvre des fichiers clés au premier lancement
        default.openFiles = [
          "<APP_DIR>/src/app/page.tsx"          # ← REMPLACER (ou supprime si hors Next.js)
        ];

        # Tu peux lancer une install automatique si tu veux :
        # run = [
        #   "npm --prefix <APP_DIR> ci"
        # ];
      };
    };

    previews = {
      enable = true;

      previews = {
        web = {
          manager = "web";
          # Next.js (npm). $PORT est fourni par l’IDE. 0.0.0.0 = écoute externe
          command = [
            "npm" "--prefix" "<APP_DIR>" "run" "dev" "--"
            "--port" "$PORT" "--hostname" "0.0.0.0"
          ];

          # Si tu utilises pnpm :
          # command = [
          #   "pnpm" "--dir" "<APP_DIR>" "dev" "--"
          #   "--port" "$PORT" "--hostname" "0.0.0.0"
          # ];

          # Si tu utilises yarn :
          # command = [
          #   "bash" "-lc"
          #   "cd <APP_DIR> && yarn dev --port $PORT --hostname 0.0.0.0"
          # ];
        };

        # Exemple Vite (dé-commente si besoin)
        # vite = {
        #   manager = "web";
        #   command = [ "bash" "-lc" "cd <APP_DIR> && npm run dev -- --port $PORT --host" ];
        # };
      };
    };
  };
}


Notice : quoi modifier et où

  1. projectId (Firebase)

    • Où : services.firebase.emulators.projectId

    • Que mettre : l’ID de ton projet Firebase local (ex. my-app-dev).

    • Astuce : si detect = true et que ton firebase.json contient déjà emulators, ça fonctionnera automatiquement, mais garde projectId cohérent.

  2. services (Firebase Emulators à lancer)

    • Où : services.firebase.emulators.services

    • Que mettre : liste exacte des émulateurs que tu utilises :

      • courants : "auth", "firestore", "functions", "storage", "pubsub", "database"
    • Évite d’en déclarer que tu n’emploies pas (ça accélère le boot et évite du bruit dans les logs).

  3. Chemins d’application

    • <APP_DIR>

      • Où : partout dans command et default.openFiles

      • Que mettre : le dossier de ton app (ex. apps/web, web, ou . si c’est à la racine).

    • Fichiers à ouvrir au démarrage

      • Où : idx.workspace.onCreate.default.openFiles

      • Que mettre : des fichiers utiles qui existent vraiment dans ton repo.

      • Exemple Next.js : "<APP_DIR>/src/app/page.tsx"
        Si tu es en pages/, mets plutôt "<APP_DIR>/pages/index.tsx".

  4. Commande de preview (Dev server)

    • Où : idx.previews.previews.web.command

    • NPM (par défaut du modèle) : garde npm --prefix <APP_DIR> run dev -- --port $PORT --hostname 0.0.0.0

    • pnpm : utilise le bloc commenté pnpm (remplace <APP_DIR>).

    • Yarn : utilise le bloc commenté yarn.

    • Vite : active le bloc vite et assure-toi qu’il passe --port $PORT --host.

  5. Version de Node

    • Où : packages = with pkgs; [ nodejs_20 … ]

    • Que mettre : nodejs_20 (LTS) ou nodejs_22 selon ton projet.

    • Astuce : aligne avec ta config (engine dans package.json, CI, etc.).

  6. Java / zulu

    • Où : packages

    • Utile si : outils qui nécessitent un JDK (certains CLIs, builds Android, etc.).

    • Sinon : tu peux le retirer sans souci.

  7. Ports fixes (optionnel)

    • Où : services.firebase.emulators.ports

    • Pourquoi : stabiliser des ports si tu as des outils externes qui s’y connectent.

    • Exemple :

      ports = { auth = 9099; firestore = 8080; };
      
      
  8. Scripts d’install auto (optionnel)

    • Où : idx.workspace.onCreate.run

    • Exemple : npm --prefix <APP_DIR> ci pour une install clean au premier boot.


Deux cas fréquents

  • App à la racine du repo

    • Remplace <APP_DIR> par .

    • Exemple commande npm :
      ["npm" "--prefix" "." "run" "dev" "--" "--port" "$PORT" "--hostname" "0.0.0.0"]

  • Monorepo (ex. apps/web)

    • Mets <APP_DIR> = "apps/web"

    • Pense à ouvrir des fichiers qui existent réellement sous apps/web.


Pièges à éviter

  • Oublier --hostname 0.0.0.0 (Next.js/Vite) → l’aperçu ne se charge pas dans l’IDE.

  • Pointer default.openFiles vers un fichier qui n’existe pas → ça n’empêche pas le démarrage, mais c’est perturbant.

  • Déclarer des émulateurs que tu n’utilises pas → plus lent / plus de logs pour rien.

  • Ne pas aligner la version Node entre dev.nix, package.json (champ engines) et ta CI.

Hello! This is a super frustrating issue, and your detailed log is incredibly helpful for diagnosing it.

I see your main suspicion is the cloud environment’s routing layer, but I think the real clue is inside your terminal log.

This combination is the key:

Bash

 ✓ Ready in 7.5s
 ...
 GET / 404 in 20402ms
 ○ Compiling /_not-found ...

This is actually great news! It means the cloud environment’s proxy is working perfectly. The request is getting to your Next.js application.

The log line GET / 404 in 20402ms is being generated by the Next.js dev server itself. It’s not a 404 from the environment’s proxy (which would be much faster and wouldn’t show up in the npm run dev log).

The 20402ms (20 seconds!) is also a huge clue. It shows that Next.js received the request and then spent a long time trying to find or compile a page for it, failed, and then finally compiled the /_not-found page to serve the 404.

So, we just need to figure out why Next.js itself can’t find your root (/) page.

Here are the most likely causes:


1. Missing Root Page (app/page.tsx)

This is the most common reason. The GET / request means the browser is asking for your homepage.

  • App Router: Do you have a src/app/page.tsx file? (Or app/page.tsx if you’re not using the src directory).

  • Pages Router: (Less likely on Next 14, but possible) Do you have a src/pages/index.tsx file?

If this file is missing, Next.js has nothing to serve for the / route and will correctly return a 404.


2. Middleware (The i18next Clue)

This is the second most likely culprit, especially since I see i18next: languageChanged es and /src/middleware compiling in your logs.

Internationalization (i18n) middleware is a common source of this exact 404 error. Your middleware.ts file is likely intercepting the / request and trying to redirect or rewrite it to a language-specific path, like /es or /en.

If you don’t have a page at that new path (e.g., src/app/[lng]/page.tsx), Next.js will return a 404.

How to Test This:

  1. Stop your dev server.

  2. Go into your src/middleware.ts file and comment out everything except a basic return NextResponse.next().

  3. Restart the dev server with npm run dev.

If your app now loads, you’ve confirmed the middleware is the problem. You’ll need to check your i18next configuration to ensure it’s correctly handling the default locale or that the [lng] routes exist.


3. Corrupted Dev Server Cache

Sometimes, the Next.js dev server just gets into a bad state. The fix is to “nuke” the cache and restart.

  1. Stop the dev server (Ctrl+C).

  2. Delete the .next folder from your project:

    Bash

    rm -rf .next
    
    
  3. Restart the server:

    Bash

    npm run dev
    
    

This forces Next.js to rebuild everything from scratch and often clears up strange routing issues.

Summary

I’m confident this isn’t a cloud environment or proxy issue. The log GET / 404 proves your Next.js app is receiving the traffic.

The problem is almost certainly one of these:

  1. A missing src/app/page.tsx file.

  2. Your middleware.ts (for i18next) is rewriting the URL to a route that doesn’t have a page.

Check on the middleware. Start by commenting it out to see if the app loads. Let us know if that works!