Hi, Vercel Community! I’m Chris from the Technical Consulting team. Today’s community post is on how you can enable Trusted Proxy on Vercel.
Context
If you’re using a reverse proxy—such as Google Cloud Load Balancing, AWS CloudFront, or Nginx—before reaching Vercel, please note: traffic routed through a reverse proxy can sometimes appear similar to a Distributed Denial of Service (DDoS) attack. This could cause Vercel’s DDoS protection to inadvertently block legitimate traffic, potentially leading to website downtime.
What is Trusted Proxy?
To help prevent this, Vercel offers a feature called Trusted Proxy, which enables our DDoS protection to distinguish between actual attacks and genuine traffic routed through a reverse proxy. Trusted Proxy is automatically enabled for Fastly, Cloudflare, Imperva CDN, Akamai, and Azure Front Door—no additional action is required for these providers.
However, if you’re using Google Cloud Load Balancing, AWS CloudFront, or another provider not on this list, please open a support case for assistance in configuring Trusted Proxy, as a few setup steps are required.
Enterprise customers using self-hosted proxies (e.g., Nginx) or with advanced needs like geolocation-based routing should contact their Customer Success Manager (CSM) for tailored support.
How to confirm Trusted Proxy is active
To ensure Trusted Proxy is working correctly, confirm that the appropriate header (from the list below) is being sent by your reverse proxy to Vercel. One way to do this is by setting up an API endpoint that echoes all request headers in the response.
- Fastly:
Fastly-Client-IP
- Google Cloud Load Balancing:
X-GCP-Connecting-IP
- Cloudflare:
CF-Connecting-IP
- AWS CloudFront:
CloudFront-Viewer-Address
- Imperva CDN (Cloud WAF):
Incap-Client-IP
- Akamai:
True-Client-IP
- Azure Front Door:
X-Azure-ClientIP
Example: Next.js Route Handler to Echo Request Headers
Here’s an example of a Next.js route handler that echoes request headers back in the response, which can help you verify that the correct headers are being passed through.
// app/api/echo-headers/route.ts
import { NextRequest, NextResponse } from "next/server";
export async function GET(request: NextRequest) {
// Convert headers to a plain object for easier reading in JSON response
const headers = Object.fromEntries(request.headers.entries());
return NextResponse.json({ headers });
}