Azure / Azure/azure-functions-host

Disallow 32-bin Windows Node App for Node 24

Open
#11,918 0 comments 0 reactions 0 assignees View on GitHub
Needs: Triage (Functions)
Dominant language
C#
Stars
2k
Forks
482
Avg merge
2d 10h
Merged PRs (30d)
36

Description

#### What problem would the feature you're requesting solve? Please describe.

App Service accepts 32-bit + Node = 23 and degrades silently to an unusable legacy Node rather than rejecting the combination. Recommend the Windows Node stack default to use32BitWorkerProcess: false for Node = 24, or block/warn at create and config-update time. This is the durable customer-facing fix: any customer on a 32-bit Windows plan selecting Node 24 hits the same failure with the same unhelpful error.

#### Describe the solution you'd like
A clear and concise description of what you want to happen.

Add ResolveNodeDefaultExecutablePath, mirroring the dotnet resolver but rooted at the x64 Program Files path (ProgramW6432), so DefaultExecutablePath is absolute instead of bare node.
Change the PATH fallback from Warning to hard startup failure when the requested Node major has no build for the current process bitness. Failing fast with a clear message beats launching an unknown interpreter.
Error text should name the real problem, e.g. "Node 24 requires a 64-bit Function App. Set use32BitWorkerProcess=false." Today the DRI-visible symptom is a bare SyntaxError with no mention of Node, bitness, or version.

Two traps for whoever writes the Host fix
Trap 1 — the existing architecture validator would NOT have caught this, and never even runs for node.

azure-functions-host/src/WebJobs.Script/RuntimeInformation/SystemRuntimeInformation.cs L16-19 returns RuntimeInformation.OSArchitecture. That is OS architecture, not process bitness — it returns X64 on a 64-bit worker VM even when the app runs as a 32-bit process. It is blind to use32BitWorkerProcess.

Worse, ValidateArchitecture (RpcWorkerDescription.cs L144-148) is only reached via ValidateDefaultWorkerPathFormatters (L118-134), which is gated on placeholder tokens being present in DefaultWorkerPath. Node's path is fixed and absolute:

C:\Program Files (x86)\SiteExtensions\Functions\4.1051.300\workers\node\dist/src/nodejsWorker.js
No placeholders => none of those validators execute for node today.

Trap 2 — a naive copy of the dotnet resolver reproduces the bug.

ResolveDotNetDefaultExecutablePath (RpcWorkerDescription.cs L160-182) uses Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) at L166. Under WOW64 that returns C:\Program Files (x86) in a 32-bit process — i.e. it resolves into the exact 32-bit tree that has no Node 24. A node resolver must use the explicit x64 root (ProgramW6432).

Also note the current fallback at L181 logs only a Warning:

File '{fullPath}' is not found, '{DefaultExecutablePath}' invocation will rely on the PATH environment variable.

Silent PATH fallback is what let a ~2015 interpreter get launched. That is the actual defect.

#### Describe alternatives you've considered

Why the Node worker cannot self-defend

The worker already has a Node version guard. It is structurally unreachable in this failure mode.

Entry point azure-functions-nodejs-worker/src/nodejsWorker.ts (branch v3.x, 18 lines total):

// line 4

const logPrefix = 'LanguageWorkerConsoleLog';
// line 6
let workerModule;

That const on line 4 is the reported SyntaxError: Use of const in strict mode. A ~2015 V8 rejects the file at parse time — before line 1 executes.

The existing guard runs far downstream:


Guard | Location | Runs at
-- | -- | --
validateNodeVersion(process.version) | src/eventHandlers/WorkerInitHandler.ts L56 | WorkerInit RPC
validateNodeVersion(process.version) | src/eventHandlers/FunctionEnvironmentReloadHandler.ts L80 | env reload
Incompatible Node.js version ${major}... | src/utils/util.ts L38 | (message text)
isNode20Plus() semver check | src/utils/util.ts L14 | (helper)

All of these require: process start -> module parse -> module load -> gRPC channel up -> WorkerInit received. The interpreter dies at step 2. The guard sits behind the very parse barrier it was meant to protect against.

So a Node-worker-only fix cannot produce a good error here. It can only make the failure slightly louder.

#### Additional context
Add any other context or screenshots about the feature request here.

Contributor guide

Open the contributing guide

Research direction

Start in azure-functions-host/src/WebJobs.Script/Description/RpcWorkerDescription.cs, especially the dotnet resolver and PATH fallback, then read SystemRuntimeInformation.cs and the referenced validator paths. Check the nodejsWorker.ts entry point only to understand why its version guard is too late. Done means Node 24 on a 32-bit process fails clearly, while the resolver uses the explicit x64 ProgramW6432 path and no silent PATH fallback remains.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, csharp, node.js
Domain
backend, cloud
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.