nextjs - ✅(Solved) Fix Encoding issue with middleware rewrites and headers [2 pull requests, 11 comments, 6 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#85631Fetched 2026-04-08 02:14:51
View on GitHub
Comments
11
Participants
6
Timeline
26
Reactions
6
Author
Timeline (top)
commented ×11subscribed ×6cross-referenced ×2labeled ×2

Error Message

Vercel Runtime Malformed Response Header Error: Header 'x-middleware-request-cf-ipcity: Montréal' contains non-ASCII characters.

Fix Action

Fix / Workaround

As of today, the only workaround is to encode/decode each header manually. Although this works technically, it is not a real solution as any other header containing a non-ASCII character can break the middleware. It also adds a lot of unnecessary code into the proxy, which should be as light as possible.

PR fix notes

PR #85880: fix: middleware header encoding for non-ASCII characters

Description (problem / solution / changelog)

What?

Fixes middleware header encoding issue where non-ASCII characters (like "Montréal") in request headers cause "Header contains non-ASCII characters" errors in Vercel deployments.

Why?

HTTP headers must be ASCII-safe. Middleware was passing non-ASCII characters without encoding, causing deployment failures.

How?

  • Added encodeHeaderValue()/decodeHeaderValue() utilities for safe encoding/decoding
  • Modified middleware response handling to encode headers
  • Modified route resolution to decode headers
  • Added comprehensive tests

Fixes #85631

Changed files

  • packages/next/src/server/lib/router-utils/resolve-routes.ts (modified, +3/-2)
  • packages/next/src/server/web/spec-extension/response.ts (modified, +2/-2)
  • packages/next/src/server/web/utils.test.ts (modified, +70/-1)
  • packages/next/src/server/web/utils.ts (modified, +41/-0)

PR #88237: fix non ascii encoded middleware header

Description (problem / solution / changelog)

Issue

Middleware crashes with "Header contains non-ASCII characters" error when processing headers containing utf-8 values (e.g. x-city: Montréal). This happens because x-middleware-request-* headers must be ASCII-safe per HTTP spec.

Additionally, when CDNs send UTF-8 header values, Node.js interprets the bytes as Latin-1, causing encoding corruption (e.g., é from "Montréal" becomes other latters).

Solution

  • Mojibake recovery: Added decodeMojibake() to detect and recover UTF-8 strings that were corrupted by Latin-1 interpretation
  • ASCII-safe encoding: Percent-encode non-ASCII header values before setting x-middleware-request-* headers
  • Minimal mode support: Use a new temp marker header x-middleware-request-encoded to track which headers need decoding

The issue happens for deployment only that the changes are only made around minimal mode.

Fixes #85631

Changed files

  • packages/next/src/server/base-server.ts (modified, +7/-3)
  • packages/next/src/server/lib/fix-mojibake.test.ts (removed, +0/-21)
  • packages/next/src/server/lib/fix-mojibake.ts (removed, +0/-14)
  • packages/next/src/server/lib/mojibake.test.ts (added, +70/-0)
  • packages/next/src/server/lib/mojibake.ts (added, +60/-0)
  • packages/next/src/server/lib/router-utils/resolve-routes.ts (modified, +10/-2)
  • packages/next/src/server/lib/server-ipc/utils.ts (modified, +1/-0)
  • packages/next/src/server/web/spec-extension/response.ts (modified, +25/-2)
  • packages/next/src/server/web/utils.test.ts (modified, +78/-1)
  • packages/next/src/server/web/utils.ts (modified, +82/-0)
  • test/e2e/non-ascii-headers/with-middleware/app/api/route-headers/route.js (added, +18/-0)
  • test/e2e/non-ascii-headers/with-middleware/app/layout.js (added, +7/-0)
  • test/e2e/non-ascii-headers/with-middleware/app/page.js (added, +3/-0)
  • test/e2e/non-ascii-headers/with-middleware/middleware.js (added, +27/-0)
  • test/e2e/non-ascii-headers/with-middleware/next.config.js (added, +1/-0)
  • test/e2e/non-ascii-headers/with-middleware/pages/api/headers.js (added, +7/-0)
  • test/e2e/non-ascii-headers/with-middleware/with-middleware.test.ts (added, +202/-0)
  • test/e2e/non-ascii-headers/without-middleware/app/api/route-headers/route.js (added, +18/-0)
  • test/e2e/non-ascii-headers/without-middleware/app/layout.js (added, +7/-0)
  • test/e2e/non-ascii-headers/without-middleware/app/page.js (added, +3/-0)
  • test/e2e/non-ascii-headers/without-middleware/next.config.js (added, +1/-0)
  • test/e2e/non-ascii-headers/without-middleware/pages/api/headers.js (added, +7/-0)
  • test/e2e/non-ascii-headers/without-middleware/without-middleware.test.ts (added, +102/-0)

Code Example

500: INTERNAL_SERVER_ERROR
Code: MIDDLEWARE_INVOCATION_FAILED
ID: cle1::w8596-1761928200824-a0b4989ee40e

---

Vercel Runtime Malformed Response Header Error: Header 'x-middleware-request-cf-ipcity: Montréal' contains non-ASCII characters.

---

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.6.0: Mon Aug 11 21:16:21 PDT 2025; root:xnu-11417.140.69.701.11~1/RELEASE_ARM64_T6000
  Available memory (MB): 32768
  Available CPU cores: 10
Binaries:
  Node: 22.18.0
  npm: 10.9.3
  Yarn: N/A
  pnpm: 8.6.12
Relevant Packages:
  next: 16.0.2-canary.2 // Latest available version is detected (16.0.2-canary.2).
  eslint-config-next: N/A
  react: 19.2.0
  react-dom: 19.2.0
  typescript: 5.9.3
Next.js Config:
  output: N/A
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://github.com/franknoel/nextjs-bug-repro-middleware-encoding

To Reproduce

  1. Deploy https://github.com/franknoel/nextjs-bug-repro-middleware-encoding
  2. Add a header with a non-ASCII value, like Montréal. I'm using Cloudflare IP geolocation, which add cf-ipcity to the request.
  3. Load a page that uses the middleware

Exemple deployment: https://nextjs-bug-repro.pcobalt.com/

Current vs. Expected behavior

Errors from Vercel:

500: INTERNAL_SERVER_ERROR
Code: MIDDLEWARE_INVOCATION_FAILED
ID: cle1::w8596-1761928200824-a0b4989ee40e
Vercel Runtime Malformed Response Header Error: Header 'x-middleware-request-cf-ipcity: Montréal' contains non-ASCII characters.

I'd expect Next.js to support non-ASCII characters, like it did seamlessly before version 16.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.6.0: Mon Aug 11 21:16:21 PDT 2025; root:xnu-11417.140.69.701.11~1/RELEASE_ARM64_T6000
  Available memory (MB): 32768
  Available CPU cores: 10
Binaries:
  Node: 22.18.0
  npm: 10.9.3
  Yarn: N/A
  pnpm: 8.6.12
Relevant Packages:
  next: 16.0.2-canary.2 // Latest available version is detected (16.0.2-canary.2).
  eslint-config-next: N/A
  react: 19.2.0
  react-dom: 19.2.0
  typescript: 5.9.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Headers

Which stage(s) are affected? (Select all that apply)

Vercel (Deployed)

Additional context

This is working with Next.js v15 with next-intl v4.4.0 and prior versions. I first contacted Vercel support and they confirmed that it's a Next.js issue. They also said that I should open an issue on GitHub to report the problem.

As of today, the only workaround is to encode/decode each header manually. Although this works technically, it is not a real solution as any other header containing a non-ASCII character can break the middleware. It also adds a lot of unnecessary code into the proxy, which should be as light as possible.

extent analysis

TL;DR

The most likely fix is to encode non-ASCII characters in headers to ensure compatibility with Next.js version 16.

Guidance

  • Verify that the issue is indeed caused by non-ASCII characters in headers by checking the Vercel error logs for "Malformed Response Header Error".
  • Consider using a library or function to automatically encode non-ASCII characters in headers, rather than manual encoding/decoding.
  • Test the middleware with different non-ASCII characters to ensure the encoding solution works for all cases.
  • Review the Next.js documentation for any updates or recommendations on handling non-ASCII characters in headers.

Example

No code example is provided as the issue does not include sufficient code context.

Notes

The provided information suggests that the issue is specific to Next.js version 16 and may not be a problem in earlier versions. The current workaround of manual encoding/decoding is not ideal and may not cover all cases.

Recommendation

Apply a workaround to encode non-ASCII characters in headers, as the issue is likely due to a change in Next.js version 16 and a fix may not be available yet. This will ensure that the middleware functions correctly until a more permanent solution is found.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

nextjs - ✅(Solved) Fix Encoding issue with middleware rewrites and headers [2 pull requests, 11 comments, 6 participants]