HttpPlatformHandler: run Node or Python behind IIS without FastCGI
Use the IIS HttpPlatformHandler extension to launch a Node or Python process, pass the dynamic port, capture stdout, and avoid process-per-request mistakes.
- Build
- 26100.33650
- Edition
- Standard / Datacenter
- Architecture
- x64
- Support
- Documentation (E1)
- Evidence
- E1Official documentation
- Verified
- 2026-10-29
- Page type
- Task
The short answer
Section titled “The short answer”HttpPlatformHandler (HPH) is an IIS extension that starts and supervises a long-running process (Node, Python, Go, etc.) and forwards requests to it. It is not FastCGI and not a process-per-request CGI.
Use it when:
- the app is a normal HTTP server listening on a port;
- you want IIS to handle TLS/bindings/logging;
- the app can read a dynamic port from
%HTTP_PLATFORM_PORT%.
For PHP, use FastCGI instead. For .NET, use the ASP.NET Core Module (ANCM), not HPH.
web.config
Section titled “web.config”<configuration> <system.webServer> <httpPlatform processPath="C:\Program Files\nodejs\node.exe" arguments="server.js" startupTimeLimit="60" stdoutLogEnabled="true" stdoutLogFile=".\logs\node"> <environmentVariables> <environmentVariable name="PORT" value="%HTTP_PLATFORM_PORT%" /> <environmentVariable name="NODE_ENV" value="production" /> </environmentVariables> </httpPlatform> </system.webServer></configuration>The app must listen on the port from %HTTP_PLATFORM_PORT%, not a hard-coded 3000. HPH assigns a port per app pool/process and proxies to it.
Python (Waitress) example:
<httpPlatform processPath="C:\Python311\python.exe" arguments="-m waitress --listen=127.0.0.1:%HTTP_PLATFORM_PORT% app:app" stdoutLogEnabled="true" stdoutLogFile=".\logs\python"></httpPlatform>The exact argument syntax depends on the app server; do not copy a Gunicorn command to Windows.
Process lifecycle
Section titled “Process lifecycle”- HPH starts the process when the app pool starts and restarts it if it exits.
startupTimeLimitcontrols how long IIS waits for the first listen.rapidFailsPerMinute(where available) prevents a crash loop from spinning forever.- The process runs as the app pool identity, so file/log permissions follow that identity.
Do not run the app as a Windows service and HPH on the same port. Pick one supervisor.
Verify
Section titled “Verify”Get-WebGlobalModule -Name HttpPlatformHandlerInvoke-WebRequest http://localhost:8080/ -UseBasicParsing | Select-Object StatusCodeGet-Content .\logs\node\*.log -Tail 50If IIS returns 502/503:
- the process did not start (path/permissions/runtime);
- it started but did not listen on
%HTTP_PLATFORM_PORT%; - it crashed after start; read the stdout log;
- the app pool identity cannot read the app directory.
When not to use HPH
Section titled “When not to use HPH”- PHP: FastCGI.
- ASP.NET Core: ANCM/Hosting Bundle.
- Static files: IIS static content.
- A process that must be shared by multiple sites: run one service and reverse-proxy with ARR instead of one HPH per site.
Lab boundary
Section titled “Lab boundary”This is E1. The lab installed IIS and PHP FastCGI, but not HPH or Node/Python. Validate the process path, port and identity on Server 2025 before calling it E2.