How to debug Azure app service slot swap failure - azure-web-app-service

I am getting the following error when trying to do a slot swap for our app service:
##[error]Error: Failed to swap App Service 'service1' slots - 'staging' and 'production'. Error: BadRequest - Cannot swap slots for site 'service1' because the application initialization in 'staging' slot either took too long or failed. Please check AppInit module configuration or try using swap with preview if application initialization time is very long. (CODE: 400)
This is what our web.config file looks like:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\XXXXXXXXXX.Services.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
<applicationInitialization>
<add initializationPage="/api/warmup" />
</applicationInitialization>
<tracing>
<traceFailedRequests>
<clear />
<add path="/api/warmup">
<traceAreas>
<add provider="ASP" verbosity="Verbose" />
<add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
<add provider="ISAPI Extension" verbosity="Verbose" />
<add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,Rewrite,iisnode" verbosity="Verbose" />
</traceAreas>
<failureDefinitions statusCodes="200-600" />
</add>
</traceFailedRequests>
</tracing>
</system.webServer>
</location>
</configuration>
The API that is used for initialization and tracing - /api/warmup - this is functioning with no issues, I am able to invoke the API manually in both the production and staging slot, successfully. In fact, in the pipeline file, I invoke this API prior to invoking the slot swap task, yet the slot swap task fails after about 45 seconds.
Further, no trace file is generated in the /LogFiles folder, and I'm not sure where next to look. I would assume a trace file would be created even when I manually invoke the API, but it's not being created, so is there maybe an issue with the web.config file?

I figured the issue - i had Configuration key WEBSITE_SWAP_WARMUP_PING_STATUSES set to 200,202. Once I removed the key, the swap completed successfully.

Related

Why Azure Web App not starting when I add maxAllowedContentLength in web.config?

I'm developing ASP.NET 7 WebApi app which is hosted on Azure Web App. I need to transfer large files. Many resources show that I need to add node in web.config, but when I add, my azure web app won't start.
My web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\WebApplication1.dll" stdoutLogEnabled="false"
stdoutLogFile="\\?\%home%\LogFiles\stdout" hostingModel="inprocess" />
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483647 " />
</requestFiltering>
</security>
</system.webServer>
</location>
</configuration>
<!--ProjectGuid: 46edd0a7-6184-47ed-a0e9-d3be7fee8b41-->
And this message is shown when I try to open web app.
As in title: Why it's not working? Do I missed some step?

Is it possible to have 2 ASP.NET Core sites in one Web App?

Is it possible to have 2 ASP.NET Core Web API apps inside the one App Service?
I understand that it would be better to have the 2 sites in separate App Services, but our use case is a bit unique.
We're trying to add the 2nd site for the purposes of using the applicationInitialization feature to introduce a delay between our app starting and the instance being given to the App Service load balancer.
I could go into a lot more detail on this, but what I desire for now is to bolt-on an additional web site that the applicationInitialization can call to delay the startup process.
I've tried:
Folder structure:
/mySite
/mySite2
web.config
Folder structure:
/mySite2
mySite.dll
web.config
With respective web.Configs looking like:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="mySite" inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\mysite\mySite.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="OutOfProcess" />
</system.webServer>
</location>
<location path="mySite2" inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\mySite2\mySite2.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="OutOfProcess" />
</system.webServer>
</location>
</configuration>
and
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\mySite.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />
</system.webServer>
</location>
<location path="mySite2" inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\mySite2\mySite2.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="OutOfProcess" />
</system.webServer>
</location>
</configuration>
YES. It is possible, you can have two applications on a single web app with a virtual directory.
From docs:
Virtual Directories are supported for Azure Websites. See Configuring
Azure Websites for what you can do through the Azure Management
Portal. From the Azure Portal, click on the Website and go to
Configure, then scroll down to virtual applications and directories
(the last config section). Just enter your virtual directory and the
physical path relative to the site root and click Save.

ASP.NET Core 2.2 Site Warmup

I've migrated a .NET Framework 4.6 WebApi to .NETCore 2.2 and am having trouble getting the IIS ApplicationInitialization module to call my endpoints on a startup/slot swap/scale out.
I added a Web.Config like:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\FR911.Api.Core.dll" stdoutLogEnabled="false" stdoutLogFile="\\?\%home%\LogFiles\stdout" hostingModel="inprocess" />
<applicationInitialization doAppInitAfterRestart="true">
<add initializationPage="api/Warmup>
<add initializationPage="/" />
</applicationInitialization>
</system.webServer>
</location>
</configuration>
But if I keep the default hosting model of "inprocess" my warmup never gets called. If I change to "outofprocess" hosting, my warmup does get called before the swap is completed.
I think the issue below is likely related:
https://github.com/aspnet/AspNetCore/issues/8057
I'm not looking to just manually ping or otherwise hit my endpoint because I want the existing feature in the module that IIS is Azure won't actually swap the endpoints until the warmup requests have finished (thus initing EFCore etc.)
Has anyone had any luck getting this to work with the inprocess hosting model?

Azure: App Service: Deploy Virtual Directory

I have an asp.net core app deployed on azure website and the domain is www.somewebsite.org. My web.config file is under site\wwwroot\web.config. Its contents are
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\App1.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout">
<environmentVariables>
</environmentVariables>
</aspNetCore>
</system.webServer>
</configuration>
I am trying to deploy another asp.net core app with the virtual path www.somewebsite.org/kiosk and I copied the complete directory under site\wwwroot\kiosk and the web.config file is under site\wwwroot\kiosk\web.config. Its contents are:
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\Kiosk.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" />
</system.webServer>
</location>
</configuration>
On Azure portal, in Application Settings for my site, I have
/ - site\wwwroot
/kiosk - site\wwwroot\kiosk
When I try going to www.somewebsite.org, the app1 site is loaded whis is correct. But, when I go to www.somewebsite.org/kiosk, the kiosk app is not being loaded. The page comes back with a 500 Internal Server Error. How do I fix this error? Is it even possible to host multiple apps from separate multiple virtual paths under one website in azure?
In my sub-application web.config file, I did the following and it started working:
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore_TEMP" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\Kiosk.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" />
</system.webServer>
</configuration>
Now, both the sites are up.
Thanks for your help.
NH
I reproduce your error, and you just need to add <location path="." inheritInChildApplications="false"> in you web.config file which is under site\wwwroot\web.config.
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\App1.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout">
<environmentVariables>
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
</configuration>

IIS 7.5 + enable PUT and DELETE for RESTFul service, extensionless

i am trying to understand how IIS 7.5 handles POST and PUT request.
I am writing a RESTful service using OpenRasta framework. The POST operation works without any problem, but the PUT operation for the same URL does not. It returns error like the following
Detailed Error Information
Module: IIS Web Core
Notification: MapRequestHandler
Handler: StaticFile
Error Code: 0x80070002
the url is like this following "http://localhost/MyService/Resource.Something.manifest"
Same setup works fine in visual studio development IIS.
Solution
Basically the default ExtensionlessUrlHandler does not accept PUT and DELETE verb. Just need to add them.
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
To get PUT and DELETE to be accepted by IIS 7.5 for a PHP 5.4 fast-CGI driven REST API I had to disable the WebDAV-module. Otherwise the WebDAV module intervenes the HTTP requests using PUT or DELETE. To get this working was however a bit confusing and I might have missed some steps or done it in another order.
These lines are placed as children of the <system.webServer>-element in web.config in the application root.
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
</handlers>
Hopes this might spare some frustration. It seems like the default setting for the server is to accept any HTTP verb not listed - see settings under Request filtering -> HTTP Verbs -> Edit feature Settings. One may consider to explicitly add the VERBS that are to be allowed. The verbs allowed may be specified appending this snippet, also as a child of <system.webServer>.
<security>
<requestFiltering>
<verbs allowUnlisted="false">
<add verb="GET" allowed="true" />
<add verb="POST" allowed="true" />
<add verb="DELETE" allowed="true" />
<add verb="PUT" allowed="true" />
</verbs>
</requestFiltering>
</security>
On a client machine one can uninstall the WebDAV module from here:
Control Panel -> Uninstall Program -> Turn Windows features on or off -> IIS -> World Wide Web Services -> Common HTTP feautre -> WebDAV Publishing
The last measure to get it working was by editing applicationhost.config found in C:\Windows\System32\inetsrv\config. Within <system.webServer> -> <handlers> you will see a php entry that has just verb="GET,HEAD,POST - amend it to add the verbs you require, e.g.:
<add name="PHP54_via_FastCGI" path="*.php" verb="GET,HEAD,PUT,DELETE,POST"/>
|
|
|
append verbs here ----------------------------------------------|
1.Go to IIS Manager.
2.Click on your app.
3.Go to "Handler Mappings".
4.In the feature list, double click on "WebDAV".
5.Click on "Request Restrictions".
6.In the tab "Verbs" select "All verbs" .
7.Press OK.
See http://learn.iis.net/page.aspx/901/iis-express-faq/ that is linked from the OR wiki.
From the link (not block-quoted for readability):
A: You can modify the IIS Express applicationHost.config in the %userprofile%\documents\IISExpress\config folder. For example to enable PUT and DELETE for extensionless Urls scroll down to the bottom of the IIS Express applicationHost.config file and look for a handler entry that starts with:
<add name="ExtensionlessUrl-Integrated-4.0" …
In the verb attribute add PUT and DELETE so the verb attribute looks like: verb="GET,HEAD,POST,DEBUG,PUT,DELETE".
My scenario was a web application in a web site on IIS 7.5. The web site had to continue to enable WebDAV, but the web application needed to turn it off in order to support PUT and DELETE in its REST API.
To get that working, the web application's Web.config needed this:
<modules runAllManagedModulesForAllRequests="true" runManagedModulesForWebDavRequests="true" >
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
</handlers>
The important difference from the other answers here is the need for runManagedModulesForWebDavRequests="true"
For me this does the trick in the web.config.
<system.webserver>
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" modules="IsapiModule" scriptProcessor="c:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<system.webserver/>
<system.web>
<authentication mode="Windows" />
<identity impersonate="true"/>
<system.web/>
I used following configuration:
IIS 7.5
Windows Server 2008 R2
Custom Application Pool, .NET 4.0, Integrated
Windows Authentication = true
Anonymous Authentication = false
Hope it helps. ;-)
URLScan tool users
If other answers still don't work and you get 404 error: these verbs may be explicitly rejected by the URLScan tool, if you have it installed.
You can configure [AllowVerbs] and [DenyVerbs] sections of the URLScan.ini file to meet your needs.
Beware of the security risks of enabling these verbs.
What worked for me was uninstalling WebDav completely.
Going into the handler mappings and setting WebDAV to handle all verbs is the only thing that worked for me, despite the fact that PUT and DELETE were already listed as handled verbs. The working web.config I have is:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<remove name="WebDAV" />
<add name="WebDAV" path="*" verb="*" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" />
</handlers>
</system.webServer>
in the web.config
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
you can also use the IIS management UI and define this globally, or default web server
I tried in IIS 8.
**uninstall WebDav Publishing
Steps to uninstall
-> Control Panel -> Go to Programs and features -> Turn windows
featues on or off-> Select Internet Information Services->World Wide
Web Services->Common HTTP Featues->"Remove" WebDAV Publishing by unchecking WebDAV option**
Reason for 500 error !
Hi all,
I want to post my own research too, I hope it would help future enthusiasts.
As suggested in answers, I can't uninstall WebDav so I have added the line below in web config (from other answers)
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
but I got a 500 error, when I have enabled debug mode found this
Cannot add duplicate collection entry of type 'add' with unique key attribute 'name' set to 'ExtensionlessUrlHandler-Integrated-4.0'
Answer
Its because there was already an ExtensionlessUrlHandler in the handler mappings section, do the following to resolve the issue.
Method 1
1) Go to Your IIS Manager and select your app
2) Go to Handler Mappings feature
3) Find ExtensionlessUrlHandler-Integrated-4.0 and delete it.
4) Add ExtensionlessUrlHandler in your webconfig (as mentioned in above answers)
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
Method 2
1) Remove ExtensionlessUrl handler from your web config
2) Click on your app in IIS Server, go to HandlerMappings
3) Find ExtensionlessUrlHandler-Integrated-4.0 (only this name, ignore others)
4) right click on it and choose Edit
edit handler
5) click on 'Request Restrictions' and select Verbs tab & choose All Verbs
this will enable extensionsless handler to allow all verbs.
I will go with method 1, as we can have control in web.config. But make sure you
check the deployment server for duplicate handler definitions.
My web.config with asp.net core 1.0
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
</system.webServer>
</configuration>
In windows server 2012.
Open applicationHost.config file in notepad with Administrator rights
applicationHost.config file is found in C:\Windows\System32\inetsrv\config
Locate the section
<verbs allowUnlisted="false" applyToWebDAV="true">
<add verb="GET" allowed="true" />
<add verb="HEAD" allowed="true" />
<add verb="POST" allowed="true" />
<add verb="DELETE" allowed="false" />
<add verb="TRACE" allowed="false" />
<add verb="PUT" allowed="false" />
<add verb="OPTIONS" allowed="false" />
</verbs>
Notice DELETE and PUT HTTP Verbs are set to false.
Change them to true.
It should now read as below
<verbs allowUnlisted="false" applyToWebDAV="true">
<add verb="GET" allowed="true" />
<add verb="HEAD" allowed="true" />
<add verb="POST" allowed="true" />
<add verb="DELETE" allowed="true" />
<add verb="TRACE" allowed="false" />
<add verb="PUT" allowed="true" />
<add verb="OPTIONS" allowed="false" />
</verbs>
Save the file. You have enabled HttpPut and HttpDelete requests on your web server
The main solution is to remove webdavmodule from the specific website'd module's section.
So you can do it from both IIS and in webconfig.
I was dealing with the same problem. The solution for me was to turn off the Firewall mode of the Web Application in Plesk Panel.

Resources