On my primary development machine, where I have tweaked and prodded IIS multiple times for many projects over the past couple of years, I get the following 500 – Internal Server Error message when I try to fire up even the simplest “Hello World” Node.JS project included in the default template for each Windows Azure Node Web Role:

image

However, when I push the default “Hello World” Node.JS app to a production on Windows Azure, I have no issues whatsoever! So what’s the problem?

Cause

The issue is that the Windows Azure emulator:

  • Creates integrated AppPools for your Node roles in IIS (hosted in iisnode), which is intended for ASP.NET applications that take advantage of the HTTP request processing pipeline in IIS 7+ and
  • Runs the AppPools under an administrative process.

Under these settings, Windows thinks that each Node.exe process is trying to access the integrated IIS pipeline (which only .NET applications can do currently) under the process identity of  the Windows Azure emulator (which has administrative rights), which is not supported. This issue comes up with other CGI / non-.NET applications run in IIS besides Node too.

Here are a few ways to fix the problem:

Fix #1: Set Identity.Impersonation=False in <system.web> in your web.config file

In this instance, simply change the web.config file in the root of your Node.JS application directory to set Identity.Impersonation=False, like this:

<system.web>
	<identity impersonate="false"/>
</system.web>

Effectively this makes it such that your Node role doesn’t not assume the identity of the Windows Azure emulator (which runs in a process with administrative rights), so it runs under a local system process identity and no longer raises the error.

Remember that web.cloud.config affects your live settings on Windows Azure; you want to change just web.config which affects only your local settings when you run in the Windows Azure emulator.

Fix #2: Set validateIntegratedModeConfiguration=False in <system.webServer> in your web.config file

Another alternative is to simply tell IIS to suppress the error altogether, which you can do be editing the system.WebServer section of your web.config file:

<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>

Fix #3: Change the AppPool to Classic Mode

The final and preferred method is to change the AppPool to Classic Mode, which shuts off the application’s access to the integrated IIS processing pipeline regardless of process identity. You can do this via startup task:

%systemroot%\system32\inetsrv\APPCMD.EXE set app "Default Web Site/" /applicationPool:"Classic .NET AppPool"

Although this might be the most kosher method of fixing the issue in IIS, it also happens to be the most awkward to implement on Azure. I’d recommend using approach #1 or #2 instead given that this issue affects the local emulator only.

If you enjoyed this post, make sure you subscribe to my RSS feed!