builds are non-deterministic (output file hashes change for no reason)
Link to the code that reproduces this issue
https://codesandbox.io/p/devbox/nextjs-bug-non-deterministic-builds-ds5czq?file=%2Ftest.sh
To Reproduce
- run the test.sh script (
./test.sh), which should soon make obvious the non-deterministic nature of builds by producing two builds with different files in their outputs, as evidenced by their differing hashes (one ouput is in theoutfolder and another in theout_backfolder).
!!!!!!!!!!!!!!!!!!!!!!!!!! TWO BUILD OUTPUTS ARE DIFFERENT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Only in out_back/_next/static/chunks/app: layout-04f3acfc83f858de.js
Only in out/_next/static/chunks/app: layout-663f360360540d96.js
Current vs. Expected behavior
Expected behavior All builds should produce the same outputs given that they use the same code and data, that is they should be deterministic.
Current behavior In this contrived example we demonstrate that it is not the case. The code is very simple (just a layout and a page), there are a few global css files and a few css modules, and already it produces non-deterministic builds, i.e. the hash of some files change between builds, and their content too (although trivially).
Provide environment information
Operating System:
Platform: linux
Arch: x64
Version: #1 SMP PREEMPT_DYNAMIC Sun Aug 6 20:05:33 UTC 2023
Available memory (MB): 4102
Available CPU cores: 2
Binaries:
Node: 20.9.0
npm: 9.8.1
Yarn: 1.22.19
pnpm: 8.10.2
Relevant Packages:
next: 14.2.0-canary.17 // Latest available version is detected (14.2.0-canary.17).
eslint-config-next: N/A
react: 18.2.0
react-dom: 18.2.0
typescript: 5.1.3
Next.js Config:
output: export
Which area(s) are affected? (Select all that apply)
App Router, Standalone mode (output: "standalone"), Static HTML Export (output: "export")
Which stage(s) are affected? (Select all that apply)
next build (local), Other (Deployed)
Additional context
As far as I can tell this problem exists since at least Next 13.4.10: https://github.com/vercel/next.js/issues/52827 And the fixes introduced by @wesleydebruijn (https://github.com/vercel/next.js/pull/55358 and https://github.com/vercel/next.js/pull/55425) have mitigated a little the issue by restricting it to css files, but it still exists.
same issue here in webpack-hash
Having same fact that same unchanged code throws errors during build and sometimes not, makes it ultra hard to predict what is happening. It is weird.
v14.3.2
Any updates on this so far?
Edit by maintainer bot: Comment was automatically minimized because it was considered unhelpful. (If you think this was by mistake, let us know). Please only comment if it adds context to the issue. If you want to express that you have the same problem, use the upvote 👍 on the issue description or subscribe to the issue for updates. Thanks!
This is causing a major problem for us when using a custom server, building on multiple architectures, and running multi-arch servers. Half of our server fleet is essentially unable to navigate client-side because the generated bundles are different.
What I've done is implement a script that checks on S3 if a build was already made (by a different server) and if so just pulls it, eitherwise builds it and pushes it to S3. This includes a check if the build is already started on a different server as well.
This way we can make sure that all assets are exactly the same.
We're experiencing the same thing. Following along with this issue we bumped Next to 14.2.21. It did fix the CSS hashing issue, but we're still seeing the problem. Interesting that the issue keeps popping up for (seemingly) different reasons.
Also discussed here #65856
Next.js Self-Hosting: Non-Deterministic Builds Still Unsolved After All Community Solutions
Hey everyone! I'm experiencing the same chunk mismatch issue that many have reported, but I've tried literally every solution from GitHub issues and community discussions without success.
My Setup:
- Next.js 15.3.1 self-hosted on AWS EKS
- Assets served from Google Cloud Storage via CloudFlare CDN
- Docker multi-stage builds with deterministic configuration
The Problem:
Browser requests main-9f8ee08d5534f3cb.js but CDN has main-95ef38955b08aed2.js, causing 404s and ERR_BLOCKED_BY_ORB errors.
What I've Tried (ALL Failed):
- ✅ Webpack deterministic config (
moduleIds: 'deterministic',chunkIds: 'deterministic',[contenthash]) - ✅ ESM externals fix (
esmExternals: false) for Next.js 14+ bug - ✅ Build-once-deploy-everywhere with Docker
- ✅ 100% environment variable consistency (32 NEXT_PUBLIC_ vars)
- ✅ Custom build ID with git hash
- ✅ Complete cache elimination (zero caching)
- ✅ Enhanced CI/CD verification with integrity checks
- ✅ Perfect GCP upload verification (241/241 files match)
Test Results:
Identical code produces different chunks:
- Build 1:
main-app-3f0d87c851dd045d.js - Build 2:
main-app-ce80d9ca6764960d.js
8+ chunks consistently change names despite zero code changes.
Question:
Has anyone found a working solution for Next.js 15.3.1 non-deterministic builds? I've implemented every GitHub issue suggestion and community recommendation, but the fundamental webpack chunk naming remains non-deterministic.
Is this a known unresolved issue with Next.js 15.x? Did downgrade to a 15x, 14x version, same issue.
Any help would be greatly appreciated! 🙏
This is a major bug that affects stability and performance.
If you containerize a Next.js build based on the SHA1 of your repository with caching enabled and then rebuild it (without any side effects of course), you could encounter an error depending on your infrastructure.
I also suspect the server action ID changes, despite no change, causing this error (between a server running build 1 and another running build 2): "Failed to find Server Action "123XYZ". This request might be from an older or newer deployment."
I try what @growebux said, plus:
- run non-parallel build, using next config experimental.workerThreads=false and experimental.cpus=1
- webpack config: optimization.mangleExports='deterministic'
@DevSide One approach I took was to build the app using Docker first and then extract the artifacts. After extraction, I validated the build manifest we had previously, ensuring that they matched; they should, in theory. If they did match, I saved the artifacts on a CDN for future access. Also, you need to update the next config to make sure it will build with the correct path (cdn/api). This solution served as an additional workaround for the non-deterministic issue we experienced in Next.js. I hope you find this solution helpful.
the weird thing about this error is that they are sometimes the same and sometimes not
I made this small script
#!/bin/bash
rm -rf b1
rm -rf b2
yarn build && mv out b1
yarn build && mv out b2
diff -r b1 b2 >out
cp b1/404/index.html b1.html
cp b2/404/index.html b2.html
npx prettier --write b1.html
npx prettier --write b2.html
diff b1.html b2.html >out2
without making ANY changes to the source code, sometimes out and out2 are 0 bytes, sometimes they are not....
Hello, any updates ?
Edit by maintainer bot: Comment was automatically minimized because it was considered unhelpful. (If you think this was by mistake, let us know). Please only comment if it adds context to the issue. If you want to express that you have the same problem, use the upvote 👍 on the issue description or subscribe to the issue for updates. Thanks!