"Failed to find Server Action" in Next.js After a Deploy: Cause and Fix, Tested
Each Server Action gets an ID when you build. The page in the browser keeps the IDs from the build it was loaded from, and sends one with every call. If the server running now was built separately and doesn't know that ID, you get this in the server log:
Error: Failed to find Server Action "40756b011ca49dc5c3d686ecdad61501f0b48cf675".
This request might be from an older or newer deployment.
Read more: https://nextjs.org/docs/messages/failed-to-find-server-actionIt mostly happens right after a deploy, to people who had the site open. I reproduced it on Next.js 16.4.4: build, open the page, rebuild and restart the server, then use the page that was already open.
What the user sees
- An action called from a client component (onClick) threw an error in the browser: Server Action "40756b…" was not found on the server. If you don't catch it, the call just fails.
- A plain <form action={save}> submit replaced the whole page with Next's error screen: "This page couldn't load. Reload to try again, or go back."
- After a reload, everything worked again, because the reloaded page had the new IDs.
Why the ID changed when the code didn't
I expected the ID to change only when the action changed. It didn't work that way:
build action ID
first build 40756b01…
clean rebuild, same code 407a81f6… (changed)
rebuild with .next folder kept, same code unchanged
clean rebuild with NEXT_SERVER_ACTIONS_ENCRYPTION_KEY set, twice 403a196a… both times
same key, action body edited unchanged
same key, action renamed changedWithout a fixed key, Next generates a new one for each clean build, and the IDs depend on it. Keeping the .next folder kept the old key, which is why this often doesn't show up locally but does on CI and hosting platforms, where every build starts clean.
The fix: a fixed encryption key
# generate once
openssl rand -base64 32
# set it as an environment variable for both build and runtime, everywhere you deploy
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY=<the value>With the same key on both builds, I loaded the page on the first build, edited the action's code, did a clean rebuild and restarted. Clicking in the page that was already open worked, and the server ran the new code. The key must be identical for every build and every server instance, so put it in your host's environment settings, not in a file that changes per build.
It doesn't help when you rename or move an action: that changed the ID even with the same key, which is correct, since the old action no longer exists. For those deploys, old pages will fail once and work after a reload.
Other causes
- Several servers built separately (for example in a container setup where each instance runs next build). Build once and run the same output everywhere, or set the same key on all of them.
- Old and new versions running at the same time during a rolling deploy. Vercel's Skew Protection sends requests from an old page to the deployment it was loaded from; other platforms need the fixed key and a way to route or reload.
- A cached HTML page served by a CDN from an older build, which still has the old IDs. Make sure HTML isn't cached longer than you expect after a deploy.
Handling it in the client
"use client";
async function onSave() {
try {
await save(data);
} catch (e) {
if (String(e).includes("was not found on the server")) {
window.location.reload(); // the page is from an older deploy
return;
}
throw e;
}
}For client-side calls, catching the error and reloading turns a failed click into one extra page load. It doesn't cover plain form submits, which is another reason to set the key.
All results come from one Next.js 16.4.4 project built with next build and run with next start on Node 26, with the page tested in Chrome.
Related
- Server Actions body size limit
- Error: NEXT_REDIRECT in Next.js
- Next.js environment variables undefined
- Next.js development