Next.js Middleware Not Running on Cloudflare Pages

Next.js middleware not running on Cloudflare Pages is a bug worth investigating from an unusual angle first: before assuming something's wrong with the middleware code itself, check which Cloudflare adapter the project is actually using — because a meaningful share of "middleware silently doesn't fire" reports trace back to @cloudflare/next-on-pages, the adapter built specifically for Cloudflare Pages, which Cloudflare has since deprecated in favor of a different deployment target entirely.
Short answer: @cloudflare/next-on-pages is deprecated, had real middleware limitations tied to its Edge-runtime-only model, and the currently recommended path is @opennextjs/cloudflare, which deploys to Cloudflare Workers rather than Pages and supports the Node.js runtime middleware needs. If you're still on the old adapter, that's very likely the actual cause. If you've already migrated and middleware still isn't firing, check whether it's specifically using Next.js 15.2's newer "Node Middleware" feature — the one current, documented gap even on the correctly updated setup.

Check the Adapter First: next-on-pages Is Deprecated
If package.json lists @cloudflare/next-on-pages, that's worth investigating before anything else. It was Cloudflare Pages' dedicated Next.js adapter, restricted to the Edge runtime with meaningfully narrower middleware support than a standard Next.js deployment — and it's now a deprecated package, no longer where Cloudflare's own guidance points teams. If middleware behaves inconsistently under this adapter, that's consistent with known limitations of a setup Cloudflare has already moved past, not a mistake specific to your code.
(If you've been comparing your middleware.ts line by line against a working Vercel deployment looking for the difference — the difference likely isn't in that file. It's in which Cloudflare platform and adapter combination is actually running it.)
The Current Recommended Setup: opennextjs/cloudflare on Workers
Cloudflare's current direction for Next.js is @opennextjs/cloudflare, deploying to Cloudflare Workers rather than Cloudflare Pages specifically — a genuine platform shift, not just a package swap:
1# Current recommended setup for a new Next.js project targeting Cloudflare
2npm create cloudflare@latest -- my-next-app --framework=next --platform=workersOpenNext's own getting-started guide walks through the setup end to end. For an existing project on the deprecated adapter, migrating means replacing @cloudflare/next-on-pages-specific APIs with their @opennextjs/cloudflare equivalents — for instance, getRequestContext becomes getCloudflareContext. The bigger change is conceptual: Workers, not Pages, is now the primary Cloudflare target for Next.js, and this adapter supports the Node.js runtime rather than restricting the whole app to Edge-only APIs, which resolves a large share of what caused middleware gaps under the older, Pages-specific setup.

The One Remaining Gap: Node Middleware Specifically
Even on the current, correctly configured setup, there's one specific documented limitation worth checking before assuming everything should just work: @opennextjs/cloudflare's own documentation is explicit that "Node Middleware" — the newer middleware variant introduced in Next.js 15.2 that runs on the Node.js runtime instead of the traditional Edge runtime — isn't yet supported by the adapter. If your middleware.ts uses that specific newer configuration, it can fail to run even on an otherwise correctly migrated Cloudflare Workers deployment, not because the migration was done wrong, but because that one particular feature genuinely isn't there yet.
1// middleware.ts — standard Edge-runtime middleware works on the current adapter
2export function middleware(request: Request) {
3 // works fine under @opennextjs/cloudflare
4}
5
6// If this project's middleware explicitly opts into Node Middleware (Next.js 15.2+),
7// that specific configuration is the current known gap — not the adapter setup generallyChecking your middleware's runtime configuration against this specific, narrow limitation is a five-minute check that rules out — or confirms — the one remaining known gap, rather than re-auditing the entire deployment from scratch.

The Opinion Part
Here's the pattern worth naming, because this bug is a particularly clean example of it: a huge amount of "how to deploy Next.js on Cloudflare" content still in circulation describes a setup — Cloudflare Pages plus next-on-pages — that Cloudflare itself has since moved past, and following that content faithfully today means correctly implementing a deprecated recommendation. The lesson generalizes past this one adapter: for any fast-moving platform-and-framework pairing, the "correct" setup from eighteen months ago is worth actively re-verifying against current official guidance before troubleshooting your own code, because the ground underneath a working setup can shift without anyone building on top of it noticing until something like middleware quietly stops firing.
Conclusion
If Next.js middleware isn't running on Cloudflare, check package.json for @cloudflare/next-on-pages first — its deprecation and Edge-only limitations explain a large share of these reports directly. Migrate to @opennextjs/cloudflare deploying to Cloudflare Workers, which is Cloudflare's current recommended path and supports the Node.js runtime middleware generally needs. If middleware still doesn't fire after that, check specifically whether it's using Next.js 15.2's Node Middleware feature, which remains the one documented gap even on the current setup.
If you're weighing Cloudflare against other platforms for a project that also needs API routes or a real backend, our guide on Next.js API routes and static export covers the architectural decision from a different but related angle, and if dynamic APIs like cookies() are a separate constraint you're navigating on the same project, our dynamic server usage guide covers that adjacent limitation.
Confirm you're on the adapter Cloudflare actually recommends today, and let middleware go back to running the way it's supposed to — quietly, reliably, in the background, exactly as intended.
Frequently Asked Questions
Historically, the @cloudflare/next-on-pages adapter — built specifically for Cloudflare Pages — only supported the Edge runtime and had known gaps in middleware feature support compared to a standard Node.js deployment. That package is now deprecated. If your project is still using it, middleware silently failing to run is a known limitation of an adapter Cloudflare itself no longer recommends, not a bug you introduced.
@opennextjs/cloudflare, deploying to Cloudflare Workers rather than Cloudflare Pages specifically. Cloudflare's own guidance now points to this adapter over the deprecated next-on-pages package, and it supports the Node.js runtime rather than restricting your app to Edge-only APIs, which resolves a large share of the compatibility gaps that caused middleware issues under the older setup.
Standard middleware works, but with one specific current gap worth knowing about: Node Middleware, the newer middleware variant introduced in Next.js 15.2 that lets middleware run on the Node.js runtime instead of Edge, is not yet supported by the adapter. If your middleware is written using that specific newer feature, it can fail to run even on the current, correctly configured Cloudflare Workers setup — not because the setup is wrong, but because that one feature genuinely isn't supported yet.
Check package.json for @cloudflare/next-on-pages specifically — if it's present, that's the deprecated, Pages-specific adapter and the likely root cause. Separately, check your middleware.ts for any explicit Node.js runtime configuration (a runtime: 'nodejs' export or similar Next.js 15.2+ Node Middleware syntax), since that specific feature is the one current gap even under the correctly migrated setup.
For most projects, no — @opennextjs/cloudflare provides a CLI-driven setup path, and the migration is primarily about replacing the deprecated adapter's specific APIs (like swapping getRequestContext for getCloudflareContext) rather than restructuring the application itself. The bigger shift is conceptual: Workers, not Pages, is now the primary Cloudflare deployment target for Next.js, which is worth knowing before troubleshooting anything else.
