OPTIONS preflight request doesn't reach IIS hosted service


I've got a localhost website and an IIS(7.5) hosted WCF service <a href="http://blogs.msdn.com/b/carlosfigueira/archive/2012/05/15/implementing-cors-support-in-wcf.aspx" rel="nofollow">implemented like this</a> with a Visual Studio debugger attached. Whenever I make a CORS request to my service I'm getting the following 404 response, along with the standard ASP.Net error page:

OPTIONS HTTP/1.1 Host: User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-gb,en;q=0.5 Accept-Encoding: gzip, deflate DNT: 1 Origin: http://localhost:51946 Access-Control-Request-Method: POST Access-Control-Request-Headers: content-type Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Response >> HTTP/1.1 404 Not Found Content-Type: text/html Server: Microsoft-IIS/7.5 X-Powered-By: ASP.NET Date: Thu, 26 Sep 2013 09:38:49 GMT Content-Length: 1245

Originally I was receiving erroneous 200 messages which didn't touch my WCF applictions numerous breakpoints, so it was being handled by IIS itself. I then followed <a href="https://stackoverflow.com/questions/14897247/jquery-stuck-at-cors-preflight-and-iis-ghost-response" rel="nofollow">this</a> and <a href="https://stackoverflow.com/a/13763025/424963" rel="nofollow">this</a> SO posts and removed the OPTIONSVerbHandler from the site and add "OPTIONS, PUT, POST & DELETE" as allowed HTTP verbs in the IIS manager UI (rather then web.conf), which progressed me to my 404 message. I've looked into WebDav which is highlighted as a problem but I haven't disabled/removed it because I don't know how but have read that it only affects "PUT & DELETE" operations where as my "POST" ops are also failing.

GET requests work as expected so the service definitely exists/works in IIS, just the Options preflight isn't reaching my service.



Although the OP managed to find a solution that worked in their specific case, the same issue has been driving me round the bend for the past few hours. In my case I knew it wasn't a code / web.config issue as the same code ran perfectly fine on my local IIS, but not on the production version.

After reading numerous posts and trying everything they suggested (including the OP's answer) I actually got round to looking at the IIS logs (should have done that first!) and found this:

2015-03-09 14:43:39 <IP Addr> GET /Rejected-By-UrlScan ~/Service.svc/H2dbImportTxtFile <Port> - <IP Addr>

This led me too:

<a href="http://www.pressthered.com/rejected-by-urlscan_404_errors/" rel="nofollow">http://www.pressthered.com/rejected-by-urlscan_404_errors/</a>

And ultimately [AllowVerbs] the section of:




I just needed to add OPTIONS.

And now the OPTIONS request gets through, and everything works.

Hope that helps some-one else who is being driven mad.


As stated in another SO post (I'm afraid I've lost it now), as mine was a WCF service I also had to change the interface of the listening service from:


[WebInvoke(Method = "POST", etc]




[WebInvoke(Method = "*", etc]



In Handler Mappings on the IIS GUI, I had to restore defaults to get back the OPTIONSVerbHandler I'd previously deleted, once done I edited it to be an IsapiModule rather than a ProtocolSupportModule, you also need to set an executable "%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll". This allowed me to make POST requests in addition to GET requests.

PUT and DELETE were still reporting 404 until I re-enabled the OPTIONSVerbHandler, then they began reporting 200 (OK), though I couldn't see them touching my web services when I attached a debugger.

There are then 3 modules called "ExtensionlessUrlHandler-*", two for 32/64bit and one for Integrated, I only changed the 32/64bit variants (running on a classic app pool) which worked for me, but for anyone using an integrated app pool some experimentation may be needed here.

Anyway I edited the 32/64bit variants, under the "Request Restrictions" button on the Verbs tab I added "PUT,DELETE" so it read "GET,HEAD,POST,DEBUG,PUT,DELETE" and everything in my CORS ready service is working


I had <remove name="OPTIONSVerbHandler"> in my handlers section of web.config. I commented it out to fix the problem!

<system.webServer> <handlers> <!--<remove name="OPTIONSVerbHandler" />--> </handlers> </system.webServer>


  • Why this JSON string created by BOOST is different than the one required by my server?
  • Get Browser to send both If-None-Match and If-Modified-Since
  • Urllib2 authentication with API key
  • Google Cloud Storage file cache and expiry issue
  • .net console app with hyperlinks?
  • Disable OPTIONS Method Jetty Server
  • Converting a Brownfield PHP Webapp to Zend Framework
  • Request map direct me to Login page in Grails
  • Fastest way to save/load data.table
  • Uploading image using Codeigniter (API)
  • VisualVM profiling hangs while instrumenting classes
  • selectInput can't populate duplicate values (using uiOutput and renderUI) in Shiny
  • R matching more than 2 conditions and return the response value
  • Where can in find the locale objects for d3.js for different countries
  • pandas parse csv with left and right quote chars
  • Custom .ToString() Formats in .rdlc Reports
  • Plot a table with R
  • Unable to install breakpoint in Eclipse: Absent Line Number Information
  • Update SQL MS Access 2010
  • Jackson mapper write id instead of entire object
  • LibGdx GLES2.0 cube texel stretching
  • Chrome breakpoint on radio doesn't fire
  • Scrolling News Ticker Jquery - Issues
  • Jhipster: How to create relationships with User entity using supplied tools?
  • Is there a way to link a linux's thread TID and a pthread_t “thread ID”
  • init_seg and warning C4073 from library code?
  • EntLib Way to Bind “Null” Value to Parameter
  • Motorola barcode scanner SDK events C#
  • Angular2 - Template reference inside NgSwitch
  • How can I run DataNucleus Bytecode Enhancer from SBT?
  • Getting the scrolling offset when storing coordinates
  • Jquery Knockout: ko.computed() vs classic function?
  • Force show.bind execution
  • How to define and use opencv mat of user type
  • Error when parsing timestamp with pandas read_csv
  • Azure Cloud Service Web Role web pages do not load
  • retrieve vertices with no linked edge in arangodb
  • FormattedException instead of throw new Exception(string.Format(…)) in .NET
  • Change div Background jquery
  • apache spark aggregate function using min value