u/Tygertbone

Hardening Next.js Middleware: Implementing an early-abort edge filter to drop bot traffic with zero compute overhead
▲ 34 r/nextjs

Hardening Next.js Middleware: Implementing an early-abort edge filter to drop bot traffic with zero compute overhead

Hey everyone,

Wanted to share an architectural lesson learned from running an active launch phase on Vercel this week.

Our app is a modern full-stack Next.js/Supabase application. Over the last 24 hours, our logs caught a sustained automated botnet probe cycling through residential ISP blocks and cloud VPS infrastructure. The traffic footprint was predictable: spamming /wp-login.php, /wp-admin/index.php, and attempting to exfiltrate root .env files.

If you let this traffic route normally through your standard Next.js page routers, you end up wasting lambda execution cycles, muddying your analytics logs, and unnecessarily waking up your database connection pools.

  1. Moving Security to Proxy Entry To completely isolate our backend from this background noise, we implemented an early-return security filter right after pathname string extraction inside apps/web/proxy.ts, before any authentication logic or ledger routines evaluate:
const url = new URL(request.url);
const path = url.pathname.toLowerCase();

if (path.startsWith('/wp-') || path.includes('.env') || path.startsWith('/.env')) {
  return new Response('Forbidden', { status: 403 });
}

Because this executes at the earliest proxy entry threshold, the automated scripts eat an immediate 403 Forbidden response from the edge global network. Lambda invocation stays at zero.

  1. Satori / Edge OG Image Font Crashes While monitoring this, we also hit a production runtime error in our Open Graph dynamic generation endpoint (/api/og/verify/[id]): Error: Unsupported OpenType signature wOF2.

If you are using Satori for dynamic canvas generation, keep this in mind: Satori does not support Brotli-compressed WOFF2 font files. If you point your font loaders to modern .woff2 assets, the layout processor reads the compressed signature header and throws a hard exception.

We resolved this by swapping our asset destinations to standard uncompressed WOFF1 (.woff) binaries and hardening the asset loader with four defensive validation rules:

Memory Capping: Implemented a strict 32-entry cache limit (FONT_CACHE_MAX) with a 1-hour TTL window to prevent container heap exhaustion.

Timeouts: Wrapped our fetch requests in an AbortController capped at 5 seconds with exponential backoff retries to prevent hung CDN calls from freezing the lambda.

Mime Validation: Explicitly validating the content-type header to prevent edge cases where a CDN 404 HTML page gets parsed as a font stream.

Graceful Degradation: Moved from Promise.all to Promise.allSettled. If a specific style variant experiences network latency, the asset engine drops to system fallbacks and finishes rendering the canvas instead of breaking the page.

Our stack is now running in a stable, permanent green posture. If anyone is running into similar Satori layout limits or edge proxy bottlenecks on Vercel, ask away below—happy to drop our exact middleware configurations.

You can view our live rendering engine and verification setups here: vauntico.com

u/Tygertbone — 1 day ago
▲ 0 r/nextjs

Ran into a weird "not implemented... yet..." fetch failure on Vercel Node runtime with ImageResponse + Next 16. Here is the workaround.

Hey all,

I spent my entire entire morning debugging a breaking production with dynamic image generation (`next/og` / Satori) using Next.16.2.6, Turbopack, and Vercel serverless functions.

I wanted to share the post-mortem because the error logs were incredibly cryptic, and it looks like it's tied to recent Vercel infra updates.

#The Problem: We were loading custom locall binary fonts (.woff2 and .ttf) to generate dynamic sharing graphics on edge/serverless routes. Originally, we used the Standard Next.js documentation pattern: `fetch(new URL('../../public/fonts/font.woff2', import.meta.url))`

Locally, everything compiled and ran fine. But the second it hit production on Vercel, the endpoint threw an intermittent 500 error: `[TypeError: fetch failed] {[cause]: Error: not implemented... yet... at <unknown> (../../../../opt/rust/nodejs.js:17:20694)}`

# The Culprit: Vercell is migrating parts of its internal Node runtime wrapper to Rust (`opt/rust/nodejs.js`). It seems this specific runtime wrapper hasn't fully implemented local network 'fetch()' resolution protocols for the internal file system asset using 'import.meta,url' at runtime yet, even though the assets exit on disk.

# The Traps We Hit Trying to Fix It:

  1. **The `fs.readFileSync` Trap:** We switched to native file systems reads rooted to 'process.cwd()'. This passed the build, but under live serverless container rotation, the physical font files weren't reliably bunded into the micro-zipped Lambda container, throwing erratic 'ENOENT' errors.
  2. **The Turbopack Dynamic String Error.** We tried to dynamically map filenames via templates strings ('/fonts/${name}'). Turbopack static analysis threw a compilation error because it couldn't statistically trace the exact asset path at build time.

# The Solution: If you are running into this exact "not implemented" engine glitch, the cleanest workaround right now is to pull your font binaries from an external deterministic CDN (like unpkg serving the raw fontsource npm package files) using a standard external 'fetch()' call. It completely bypasses the isolated local container environment and resolves instantly with a 200 OK.

Has anyone else run into this specific `opt/rust/nodejs.js` internal fetch limitation on recent Vercel builds, or did you find a way to force locale file bundling without relying on an external network request?

reddit.com
u/Tygertbone — 3 days ago