nextjs - ✅(Solved) Fix `generateEtags` config doesn't apply to `next/image` responses [2 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#91684Fetched 2026-04-08 01:02:30
View on GitHub
Comments
0
Participants
1
Timeline
5
Reactions
0
Participants
Timeline (top)
cross-referenced ×2issue_type_added ×1labeled ×1referenced ×1

Fix Action

Fixed

PR fix notes

PR #91707: fix(image): respect generateEtags config for next/image responses

Description (problem / solution / changelog)

Summary

Fixes #91684

The generateEtags: false config option correctly suppresses ETags for page and static asset responses, but was not applied to image optimization responses served by /_next/image.

Root Cause

In packages/next/src/server/image-optimizer.ts, the setResponseHeaders() and sendResponse() functions call sendEtagResponse() unconditionally without checking the generateEtags config.

In next-server.ts, sendResponse() is called without passing this.nextConfig.generateEtags.

Fix

  • Add generateEtags: boolean = true parameter to setResponseHeaders() and sendResponse() in image-optimizer.ts
  • Guard sendEtagResponse() with the generateEtags flag
  • Pass Boolean(this.nextConfig.generateEtags) when calling sendResponse() in next-server.ts

The default parameter value (true) preserves backward compatibility.

Testing

Before this fix:

curl -sI 'http://localhost:3000/_next/image?url=%2Ftest.jpg&w=256&q=75'
# ETag: ... (wrong — should be absent)

After this fix with generateEtags: false in next.config.ts:

curl -sI 'http://localhost:3000/_next/image?url=%2Ftest.jpg&w=256&q=75'
# No ETag header (correct)

Changed files

  • packages/next/src/server/image-optimizer.ts (modified, +7/-4)
  • packages/next/src/server/next-server.ts (modified, +2/-1)

PR #91709: fix(next/server): Respect generateEtags config for next/image responses and fix JSX guard

Description (problem / solution / changelog)

What?

The generateEtags option in next.config.js was not being respected by the next/image image optimization handler. Even when generateEtags: false was explicitly set, ETag headers were still being generated and returned in next/image responses. This PR also fixes an incorrect JSX guard in the server response path.

Why?

The generateEtags config is a documented, user-facing option that allows developers to disable ETag generation — commonly needed when using external caching layers (e.g., Cloudflare, Varnish) or when implementing custom cache strategies. Silently ignoring this config for image responses creates inconsistent behavior: HTML pages respect the config, but image responses do not, leading to unexpected 304 Not Modified responses or cache mismatches depending on the setup.

The JSX guard bug could cause incorrect branching in the server render path, potentially affecting response correctness under certain rendering conditions.

How?

  • Threaded the generateEtags flag from NextServer config down into the image optimization response handler so it is checked before setting the ETag header on image responses.
  • Fixed the JSX guard condition in the server path to correctly reflect the intended logic, preventing the wrong branch from being taken during server-side rendering.

Fixes #91684

Changed files

  • packages/eslint-plugin-next/src/rules/no-duplicate-head.ts (modified, +2/-1)
  • packages/next/src/server/image-optimizer.ts (modified, +4/-1)
  • packages/next/src/server/next-server.ts (modified, +1/-0)

Code Example

curl -sI http://localhost:3000/_next/static/chunks/<hash>.js

---

curl -sI "http://localhost:3000/_next/image?url=%2Ftest.jpg&w=256&q=75"

---

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.0.0: Wed Sep 17 21:38:03 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_T8112
  Available memory (MB): 24576
  Available CPU cores: 8
Binaries:
  Node: 24.14.0
  npm: 11.9.0
  Yarn: N/A
  pnpm: 10.14.0
Relevant Packages:
  next: 16.2.1-canary.1 // Latest available version is detected (16.2.1-canary.1).
  eslint-config-next: N/A
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3
Next.js Config:
  output: N/A
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://github.com/akhilsugunan77/nextjs-etag-repro

To Reproduce

  1. Start the production server (npm run build && npm start)

  2. Request the any static chunk and inspect headers:

    curl -sI http://localhost:3000/_next/static/chunks/<hash>.js

    No ETag headergenerateEtags: false is respected.

  3. Request an optimized image and inspect headers:

    curl -sI "http://localhost:3000/_next/image?url=%2Ftest.jpg&w=256&q=75"

    ETag header is presentgenerateEtags: false is ignored.

Current vs. Expected behavior

I expected adding generateEtags: false in next config, will disable etag generation for all request. Currently it disables for pages and for static assets (_next/static/).

Static assets: <img width="2685" height="163" alt="Image" src="https://github.com/user-attachments/assets/900beba9-da6f-4e63-aca3-c6c923ba0220" />

But for image request it still generates etag <img width="2685" height="119" alt="Image" src="https://github.com/user-attachments/assets/2983dc9f-e03c-4dd8-b837-b2da7cc05308" />

Expected behaviour should be disabling etag generates for all requests.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.0.0: Wed Sep 17 21:38:03 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_T8112
  Available memory (MB): 24576
  Available CPU cores: 8
Binaries:
  Node: 24.14.0
  npm: 11.9.0
  Yarn: N/A
  pnpm: 10.14.0
Relevant Packages:
  next: 16.2.1-canary.1 // Latest available version is detected (16.2.1-canary.1).
  eslint-config-next: N/A
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Image (next/image)

Which stage(s) are affected? (Select all that apply)

next build (local), next start (local), next dev (local)

Additional context

No response

extent analysis

Fix Plan

To fix the issue of generateEtags: false being ignored for image requests, you need to disable ETag generation for the next/image module as well.

Here are the steps:

  • Update your next.config.js file to include the following configuration:
module.exports = {
  //... other configurations ...
  images: {
    disableStaticImages: true,
  },
  generateEtags: false,
}

However, the above configuration will disable static image generation. If you still want to use static images, you can try the following approach:

  • Create a custom getStaticProps function for your image component to manually handle ETag generation.
  • Alternatively, you can use a custom middleware to remove the ETag header from the response.

Here's an example of how you can create a custom middleware to remove the ETag header:

// middleware/removeEtag.js
export default function removeEtag(req, res, next) {
  res.removeHeader('ETag');
  next();
}

Then, in your next.config.js file, add the middleware to the experimental section:

module.exports = {
  //... other configurations ...
  experimental: {
    middleware: [(req, res, next) => removeEtag(req, res, next)],
  },
  generateEtags: false,
}

Note that this is a temporary workaround and may have performance implications.

Verification

To verify that the fix worked, you can run the following commands:

curl -sI http://localhost:3000/_next/static/chunks/<hash>.js
curl -sI "http://localhost:3000/_next/image?url=%2Ftest.jpg&w=256&q=75"

Check the response headers to ensure that the ETag header is not present.

Extra Tips

  • Make sure to test your application thoroughly after applying the fix to ensure that it works as expected.
  • If you're using a CDN or caching layer, you may need to invalidate the cache or update the CDN configuration to reflect the changes.
  • Consider opening an issue with the Next.js team to report the bug and request a permanent fix.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

nextjs - ✅(Solved) Fix `generateEtags` config doesn't apply to `next/image` responses [2 pull requests, 1 participants]