vercel/next.js · error · Error
The key "${key}" under "env" in ${config.configFileName || '
Error message
The key "${key}" under "env" in ${config.configFileName || 'config'} is not allowed. https://nextjs.org/docs/messages/env-key-not-allowed What it means
Thrown by errorIfEnvConflicted() when a key in the next.config.js `env` map matches a reserved pattern. Next.js forbids NODE_* (e.g. NODE_ENV, NODE_OPTIONS), any __-prefixed key, and the literal NEXT_RUNTIME, because assigning those via config would shadow or break Node/Next internal behavior. The check runs while collecting static env vars for the build.
Source
Thrown at packages/next/src/lib/static-env.ts:14
import type {
NextConfigComplete,
NextConfigRuntime,
} from '../server/config-shared'
function errorIfEnvConflicted(
config: NextConfigComplete | NextConfigRuntime,
key: string
) {
const isPrivateKey = /^(?:NODE_.+)|^(?:__.+)$/i.test(key)
const hasNextRuntimeKey = key === 'NEXT_RUNTIME'
if (isPrivateKey || hasNextRuntimeKey) {
throw new Error(
`The key "${key}" under "env" in ${config.configFileName || 'config'} is not allowed. https://nextjs.org/docs/messages/env-key-not-allowed`
)
}
}
/**
* Collects all environment variables that are using the `NEXT_PUBLIC_` prefix.
*/
export function getNextPublicEnvironmentVariables() {
const defineEnv: [string, string | undefined][] = []
for (const key in process.env) {
if (key.startsWith('NEXT_PUBLIC_')) {
const value = process.env[key]
if (value != null) {
defineEnv.push([`process.env.${key}`, value])
}
}
}View on GitHub (pinned to 0ae8c72462)
Solutions
- Remove the offending key (NODE_*, __*, or NEXT_RUNTIME) from the `env` map in your next.config file.
- Set NODE_ENV via the actual process environment (e.g. in your hosting platform or package.json script) rather than the `env` config.
- If you need a custom var, rename it to a non-reserved prefix (e.g. APP_NODE_ID instead of NODE_ID).
Example fix
// before (next.config.js)
module.exports = { env: { NODE_ENV: 'production', NEXT_RUNTIME: 'nodejs' } }
// after
module.exports = { env: { APP_RELEASE: 'v1' } } // NODE_ENV set by the platform, not config Defensive patterns
Strategy: validation
Validate before calling
const RESERVED_ENV_KEY = /^(?:NODE_.+)|^(?:__.+)$/i
function validateEnvKeys(env: Record<string, unknown>) {
for (const key of Object.keys(env)) {
if (RESERVED_ENV_KEY.test(key) || key === 'NEXT_RUNTIME') {
throw new Error(`Reserved env key '${key}' cannot be set in next.config env`)
}
}
} Type guard
function isAllowedEnvKey(key: string): boolean {
return !(/^(?:NODE_.+)|^(?:__.+)$/i.test(key) || key === 'NEXT_RUNTIME')
} Prevention
- Never put NODE_*, __*, or NEXT_RUNTIME in the next.config `env` map.
- Set NODE_ENV via the process environment (platform/script), not config.
- Review the `env` block after copying variables from a .env file.
When it happens
Trigger: Setting env: { NODE_ENV: 'production' }, env: { __NEXT_DATA__: '...' }, or env: { NEXT_RUNTIME: 'nodejs' } in next.config.js or next.config.ts. Any key matching /^(?:NODE_.+)|^(?:__.+)$/i or exactly 'NEXT_RUNTIME' triggers it.
Common situations: Copying environment variables wholesale into the `env` config block (a common mistake when migrating from .env files), or attempting to override Node runtime flags via config. Often seen when developers try to force NODE_ENV in config rather than via the environment.
Related errors
- NEXT_EXPORT_ERROR
- Failed to resolve pattern "${patterns.join(',')}": ${error.m
- Could not parsetsconfig.json. Please make sure it contains s
- The NEXT_DEPLOYMENT_ID environment variable value "${process
- Command failed: ${command} ${args.join(' ')} (exit ${code})
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/af632575993fcef0.
Report an issue: GitHub.