Cause 1 · in 2 of 3 matching casesThe variable was not set in the environment that runs the build
Locally, Next.js reads the value from a .env file, which is normally excluded from the repository. The build host has no such file, so you must set the value in its environment variable settings, scoped to the environment being built. If your code throws on undefined, a missing value fails the build. If your code falls back to a placeholder, the build ships the placeholder, for example a mock sign-in picker or a localhost site URL in robots.txt.
How to tell: The variable exists in your local .env.local but is missing from the host's settings for the Production or Preview environment that failed.
The value was added or changed after the deployment was built
A NEXT_PUBLIC_ value is fixed when the build runs. Editing it in the host's settings does not change an existing deployment. The live site keeps the old value, or undefined, until the next build.
How to tell: The settings page shows the right value, but the live bundle still has the old one and the deployment is older than the edit.
The name has no NEXT_PUBLIC_ prefix
Next.js does not send variables without the prefix to the browser. They resolve on the server and are undefined in client code. A rename or a typo in the prefix produces this symptom.
How to tell: The same variable works in a Route Handler or Server Component but is undefined in a Client Component.
Client code reads the variable through a dynamic lookup
Next.js inlines the literal expression process.env.NEXT_PUBLIC_NAME. It does not replace a read through a variable key or through an alias of process.env, so the browser sees undefined even when the build had the value.
How to tell: Client code uses process.env[name] or reads from const env = process.env.