Skip to content

CSP header missing in 304 responses for static assets served by next/dist/compiled/send #78815

@nicole0707

Description

@nicole0707

Link to the code that reproduces this issue

https://github.com/nicole0707/nextjs-304-csp-example

To Reproduce

  • Serve a static file (e.g., /trusted-lib.js) with a valid Content-Security-Policy header.
  • Load it once in the browser.
  • Refresh the page or re-request the asset after it is cached.
  • Observe that the 304 response omits the CSP header.

Current vs. Expected behavior

When a static asset is served with a 304 Not Modified response, the Content-Security-Policy (CSP) header is not included, even if it was present in the original 200 OK response.

This causes the CSP header to be missing in the response, or fallback to the default CSP policy from the CDN or browser context. As a result, some browsers may block the asset or apply unintended restrictions under strict CSP enforcement.

The issue appears to stem from the internal usage of a precompiled version of send under next/dist/compiled/send, which omits custom headers for 304 responses by default.

The official send package addressed this issue years ago - pillarjs/send@f53edbb , but the version bundled with Next.js seems outdated or modified.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.4.0: Fri Apr 11 18:32:05 PDT 2025; root:xnu-11417.101.15~117/RELEASE_ARM64_T8132
  Available memory (MB): 32768
  Available CPU cores: 10
Binaries:
  Node: 23.11.0
  npm: 10.9.2
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 15.3.1 // Latest available version is detected (15.3.1).
  eslint-config-next: N/A
  react: 19.1.0
  react-dom: 19.1.0
  typescript: 5.8.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)

next dev (local), next start (local)

Additional context

Please consider updating the internal version of send used in next/dist/compiled/send to the latest official version, which supports preserving headers in 304 responses.

Metadata

Metadata

Assignees

No one assigned

    Labels

    HeadersRelated to the async headers() function.locked

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions