Skip to main content
CDN

Request and response headers

Trusted platform headers Easel adds for routing, observability, security, and cache diagnostics.

Easel adds a small set of trusted headers to requests and responses for routing, observability, security, and cache diagnostics.

Use documented headers when application behavior depends on platform metadata. Undocumented internal headers may change without notice and are not a stable interface.

Request headers

Easel can attach trusted metadata before forwarding a request to application code.

These headers describe the request as observed by Easel rather than values supplied directly by the client.

Request ID

X-Easel-Id: req_01J...

A unique identifier for the request.

Use this value to correlate:

  • client responses
  • function logs
  • platform logs
  • traces
  • firewall events
  • support investigations

The same request ID may also be returned in the response.

Do not generate or overwrite this header in application code.

Deployment metadata

On function invokes, Easel may expose deployment context through documented request headers.

For example:

X-Deployment-Id: dpl_01J...
X-Easel-Deployment-Environment: production

Possible environment values:

production
preview
development

Use deployment metadata for diagnostics and environment-aware behavior.

Prefer project environment variables for ordinary application configuration. Request headers must not replace stable configuration such as database URLs, API credentials, or feature flags.

Function region

Dynamic requests may include the region in which application code is running:

X-Easel-Function-Region: iad

This can help diagnose latency relative to your databases and APIs.

Functions currently run in US East (iad). The header identifies that compute region on the request your application receives.

Do not store application state locally based on region headers. Function instances remain ephemeral and independently scalable.

Forwarded headers

Easel may forward standardized proxy information using headers such as:

Forwarded: for=203.0.113.42;proto=https;host=example.com

or:

X-Forwarded-For: 203.0.113.42
X-Forwarded-Proto: https
X-Forwarded-Host: example.com

X-Forwarded-Proto is the protocol the visitor used when connecting to Easel. For deployed applications, the expected value is normally https.

X-Forwarded-Host is the hostname requested by the visitor before internal routing or rewrites. Use it when application behavior depends on the public hostname, such as canonical URLs, domain-specific branding, or authentication callback URLs. Validate hostnames before using them to construct security-sensitive URLs.

Clients or upstream proxies can send forwarded headers themselves. Treat them as proxy metadata, not as proof of identity, unless your integration documents a trusted proxy chain.

Frameworks may expose the same information through their own request APIs.

Trust boundaries

Headers received from the public internet are untrusted.

Easel overwrites documented platform headers where required for routing and diagnostics. Client-supplied values do not control routing or security decisions.

For example, sending:

X-Easel-Function-Region: iad
X-Easel-Cache: HIT
X-Easel-Firewall-Action: allow

does not control Easel’s internal routing or security behavior.

Only values attached by Easel after the request enters the platform must be treated as trusted platform metadata.

Reading request headers

Web standard Request API

export async function GET(request: Request) {
  const requestId = request.headers.get("x-easel-id");
  const environment = request.headers.get(
    "x-easel-deployment-environment",
  );
  const region = request.headers.get("x-easel-function-region");

  return Response.json({
    requestId,
    environment,
    region,
  });
}

Header names are case-insensitive.

Next.js App Router

import { headers } from "next/headers";

export async function GET() {
  const requestHeaders = await headers();

  return Response.json({
    requestId: requestHeaders.get("x-easel-id"),
    environment: requestHeaders.get("x-easel-deployment-environment"),
    region: requestHeaders.get("x-easel-function-region"),
    deploymentId: requestHeaders.get("x-deployment-id"),
  });
}

Use the framework’s normal request-header API where available.

Response headers

Easel adds response headers that help identify the request path, cache result, security decision, and platform behavior.

Request ID

X-Easel-Id: req_01J...

The identifier associated with the request.

Use this value when searching logs or reporting a specific failed request.

Cache result

X-Easel-Cache: HIT

Indicates how the CDN cache handled the request.

ValueMeaning
HITA fresh cached response was served
STALEA stale cached response was served within an explicit stale-while-revalidate window while refreshing in the background
MISSNo usable fresh or SWR-eligible stale entry was found; origin or regeneration ran
BYPASSThe request or response was not eligible for shared caching

See Caching for eligibility and debugging.

Age

Age: 42

The number of seconds a response has spent in a shared cache.

Age may be present depending on the serving path. Treat X-Easel-Cache as the authoritative cache-result header. Absence of Age is not an error.

When both are present:

X-Easel-Cache: HIT
Age: 42

the cached entry has been stored for approximately 42 seconds.

Server

Server: Easel

Identifies Easel as the response-serving platform.

Applications must not depend on this header for behavior or security decisions.

Content encoding

Content-Encoding: br

Indicates that Easel or the application compressed the response.

Common values include:

br
gzip

Responses may also include:

Vary: Accept-Encoding

See Compression.

Firewall diagnostics

When available, Easel may include supported firewall metadata such as:

X-Easel-Firewall-Action: allow
X-Easel-Firewall-Rule-Id: rule_01J...

These headers can help explain why a request was allowed, blocked, or challenged.

Firewall metadata may be omitted when it would reveal sensitive security information or when no project rule was involved.

Do not expose internal rule identifiers to end users unless they are useful for support or administrative diagnostics.

See Security.

Preview indexing policy

Preview deployments include:

X-Robots-Tag: noindex, nofollow, noarchive

This discourages search engines from indexing preview environments.

The header does not provide access control. Anyone with the preview URL may still be able to access the deployment unless authentication or another access policy is enabled.

HSTS

HTTPS responses include:

Strict-Transport-Security: max-age=63072000

This instructs compatible browsers to use HTTPS for future requests to the hostname.

See HTTPS and TLS for behavior and configuration guidance.

Cache policy headers

Applications control browser and shared-cache behavior with response headers such as:

Cache-Control: public, max-age=0, must-revalidate
CDN-Cache-Control: public, s-maxage=3600
Cache-Tag: products product:123

Easel may consume CDN-specific directives while preserving the browser-facing policy.

See:

Custom response headers

Applications can return their own response headers.

export async function GET() {
  return Response.json(
    { ok: true },
    {
      headers: {
        "Cache-Control": "public, max-age=0",
        "CDN-Cache-Control": "public, s-maxage=300",
        "X-App-Version": "2026-08-06",
      },
    },
  );
}

You can also define headers through supported framework configuration or project routing rules.

Custom headers must not use reserved Easel header names.

Reserved headers

Do not rely on setting or overriding documented platform headers.

Examples include:

X-Easel-Id
X-Easel-Cache
X-Easel-Function-Region
X-Easel-Firewall-Action
X-Easel-Firewall-Rule-Id
X-Easel-Deployment-Environment
X-Deployment-Id

Easel may replace, remove, or ignore these values.

Use your own application namespace for custom diagnostics:

X-My-App-Version: 42
X-My-App-Trace: checkout

Hop-by-hop headers

Hop-by-hop headers apply only to one network connection and are not forwarded unchanged across proxies.

Examples include:

Connection
Keep-Alive
Proxy-Authenticate
Proxy-Authorization
TE
Trailer
Transfer-Encoding
Upgrade

Applications must not depend on receiving or controlling these headers through the CDN.

WebSocket upgrade behavior, where supported, is documented separately from ordinary HTTP request forwarding.

Header size and limits

Requests and responses are subject to platform limits for:

  • total header size
  • individual header size
  • number of headers
  • cookie size
  • URL length

Requests exceeding supported limits may be rejected before application code runs.

Responses exceeding supported limits may fail or have unsupported headers removed.

Privacy and sensitive data

Headers may appear in:

  • access logs
  • function logs
  • traces
  • error reports
  • support diagnostics

Do not place secrets or sensitive personal data in custom headers unless the application requires it and the value is handled appropriately.

Avoid logging:

Authorization
Cookie
Set-Cookie
API keys
session tokens
password reset tokens

Use request IDs to correlate events instead of copying authentication values into logs.

Inspecting response headers

Use curl:

curl -I https://example.com

Example response:

HTTP/2 200
Cache-Control: public, max-age=0, must-revalidate
CDN-Cache-Control: public, s-maxage=300
X-Easel-Id: req_01J...
X-Easel-Cache: HIT
Content-Encoding: br
Server: Easel

For redirects, include only the response headers:

curl -I http://example.com

To follow redirects:

curl -IL http://example.com

Inspecting request metadata

Create a temporary diagnostic route that returns only non-sensitive headers:

export async function GET(request: Request) {
  const names = [
    "x-easel-id",
    "x-forwarded-proto",
    "x-forwarded-host",
    "x-easel-deployment-environment",
    "x-easel-function-region",
    "x-deployment-id",
  ];

  const result = Object.fromEntries(
    names.map((name) => [name, request.headers.get(name)]),
  );

  return Response.json(result, {
    headers: {
      "Cache-Control": "private, no-store",
    },
  });
}

Remove diagnostic routes after testing. Do not return cookies, authorization headers, or other secrets to the browser.

Troubleshooting

A request header is missing

Check whether:

  • the header is supported for the current route type
  • the request reached application compute
  • the framework or adapter removes it
  • a local development server is being used
  • an upstream proxy changed the request
  • the feature is available for the current project plan

Some platform headers are present only on deployed requests and not during local development. Deployment and region headers are typically present on function invokes.

X-Easel-Cache is always BYPASS

Check for:

  • Set-Cookie
  • Authorization
  • Range
  • Cache-Control: private
  • Cache-Control: no-store
  • Cache-Control: no-cache
  • no positive shared-cache TTL
  • an unsupported method or status

See Caching.

The request ID does not appear in function logs

The request may have completed before invoking the function.

Possible reasons include:

  • firewall block
  • redirect
  • cache hit
  • static asset response
  • middleware-generated response

Platform request logs may still contain the request ID even when no function executed.

A custom header disappears

The header may be:

  • reserved by Easel
  • hop-by-hop
  • disallowed by the framework
  • removed by an upstream proxy
  • larger than a platform limit
  • overwritten by routing or project configuration

Use a non-reserved application header name and inspect both preview and production responses.

Headers differ between preview and production

Preview environments may add indexing, access-control, deployment, or diagnostic headers that do not appear in production.

Application configuration and environment-specific routing rules can also differ.