sveltejs / sveltejs/kit

SvelteKit generates large Link header, causing a 502 with Nginx

Open
#11,084 21 comments 37 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

documentation
Dominant language
JavaScript
Stars
20.8k
Forks
2.3k
Avg merge
1d 16h
Merged PRs (30d)
156

Description

Describe the bug

When the app grows, the Link header becomes bigger and bigger.

At a certain point, nginx will display 502s and error. This happens when the Link header nears 4kb.

It's possible to work around this by tweaking nginx config, but this error is hard to diagnose and it shouldn't happen out of the blue with the most popular reverse proxy.

Reproduction

In the handle hook, you can add this to reproduce it happening:

  response.headers.set("Link", '<../_app/immutable/assets/0.ff6c1858.css>; rel="preload";as="style"; nopush, <../_app/immutable/assets/Picture.c1d98be5.css>; rel="preload";as="style"; nopush, <../_app/immutable/assets/TagWidget.72afa9c1.css>; rel="preload";as="style"; nopush, <../_app/immutable/entry/start.0dc7e3e4.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/scheduler.988dae19.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/singletons.e5596c1f.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/index.a60158c4.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/parse.bee59afc.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/control.f5b05b5f.js>; rel="modulepreload"; nopush, <../_app/immutable/entry/app.1da9b740.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/index.1bccfb63.js>; rel="modulepreload"; nopush, <../_app/immutable/nodes/0.bd51b068.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/stores.d576e56f.js>; rel="modulepreload"; nopush, <../_app/immutable/nodes/2.ef69061c.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/each.b3fec9fd.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/spread.8a54911c.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/PriceTag.75c37345.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/Currency.f4aa72d9.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/navigation.d8b65ae8.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/UrlDependency.890b5d7a.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/Popup.8fb9ab92.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/Picture.0211812c.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/i18n.778889ac.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/get.281b793c.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/isObject.a95a320a.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/sumCurrency.70129a10.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/forms.95e660af.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/CartQuantity.2e07a451.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/Product.1a4e99bd.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/IconTrash.cae74cb4.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/menu-outlined.dac218ab.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/index.31109bbe.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/index.40b40403.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/fixCurrencyRounding.23ca317a.js>; rel="modulepreload"; nopush, <../_app/immutable/nodes/73.490ea325.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/globals.7f7f1b26.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/IconInfo.a1558468.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/User.f841f874.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/CmsDesign.9bb48773.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/ChallengeWidget.b02d14bf.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/Trans.03e3bf42.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/CarouselWidget.4a977ec0.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/bundle-mjs.312aa90d.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/ProductType.b9015098.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/typedKeys.2a0d164f.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/TagWidget.9ff1cfe2.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/hasIn.9eb1248f.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/index.c336cdc8.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/index.65d14ac1.js>; rel="modulepreload"; nopush, <../_app/immutable/chunks/index.ac617c56.js>; rel="modulepreload"; nopush');

Then if sveltekit is running behind nginx with default config, it will send a 502.

Logs
Nginx error log:

2023/11/20 01:18:04 [error] 788760#788760: *5288880 upstream sent too big header while reading response header from upstream, client: 145.224.88.62, server: XXX, request: "GET /XXX HTTP/2.0", upstream: "http://127.0.0.1:3000/XXX", host: "XXX"
System Info
System:
    OS: Linux 5.15 Ubuntu 22.04.2 LTS 22.04.2 LTS (Jammy Jellyfish)
    CPU: (2) x64 Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz
    Memory: 2.62 GB / 7.76 GB
    Container: Yes
    Shell: 5.1.16 - /bin/bash
  Binaries:
    Node: 18.16.1 - /usr/local/bin/node
    npm: 9.5.1 - /usr/local/bin/npm
    pnpm: 8.3.1 - /usr/local/bin/pnpm
  npmPackages:
    @sveltejs/adapter-node: ^1.2.3 => 1.2.3 
    @sveltejs/kit: ^1.27.3 => 1.27.3 
    svelte: ^4.2.2 => 4.2.2 
    vite: ^4.2.1 => 4.2.1
Severity

serious, but I can work around it

Additional Information

This can be fixed on Nginx side with this:

proxy_busy_buffers_size   512k;
proxy_buffers   4 512k;
proxy_buffer_size   256k;

Still, this error is hard to debug and it shouldn't happen with the most popular reverse proxy

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reproduction in the handle hook and run the SvelteKit app behind nginx using its default configuration. Inspect how the Link response header is produced as the application grows, then verify behavior against nginx's upstream header limit and the provided error log. Done means the reported 502 scenario is addressed or its supported behavior is clearly established.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.