nginxnuxt.jsvitenuxt3.jscaddy

ECONNRESET / 502 Bad Gateway when using Nuxt 3 behind a reverse proxy


I use a Caddy reverse proxy for my Nuxt 3 application. When loading the site in development mode, hundreds and hundreds of files will be loaded because Vite uses native ESM to provide a short warm up time and fast HMR (Hot Module Reloading). This is not a problem when accessing the site through localhost. But when going through the reverse proxy, after a few hundred files, it crashes. The browser will see a 502 (Bad Gateway) and Nuxt will report in the terminal:

 ERROR  [unhandledRejection] connect ECONNRESET 127.0.0.1:64927                                                                                                                                                                                                                                                                                                                                                                                                                         3:41:34 PM

  at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1611:16) (repeated 9 times)

This does not happen when using the Nuxt app in production mode (nuxt build + nuxt start), presumable because the files are bundled then. Curiously, the same problem appears when using Nginx as a reverse proxy.


Solution

  • Took a long time, to figure this out. Apparently, Nuxt (or Vite / Nitro.js / Node or whatever is providing the actual HTTP server) only provides HTTP 1.1. The reverse proxy of Caddy or Nginx will use HTTP 2, by default. I'm not exactly certain, why that is a problem, but this is my theory: HTTP 1.1 has a restriction of about 8 concurrent requests. Because HTTP 2 works differently, it doesn't have that restriction. So the reverse proxy will dump a lot of requests on the Nuxt server, almost at once. These have a short timeout which will ultimately lead to the connection breaking down.

    The solution was to instruct Caddy in the global options to use HTTP 1 (which is not a problem in a development environment):

    {
            servers {
                    protocols h1
            }
    }
    

    See: https://caddyserver.com/docs/caddyfile/options#protocol