How to configure a HTTP endpoint for Exchange Web Services in Exchange 2010

In Exchange 2007 if you wanted to enable HTTP for Exchange Web Services all you had to do was go into Internet Information Services (IIS) and uncheck the box 'Require secure channel (SSL)' on the EWS virtual directory.  In Exchange 2010 RTM this is no longer possible.  IIS still gives you this option; however it does not give you the behavior you are expecting.  If you uncheck this box and attempt to make a request using HTTP you receive a HTTP 404 Resource Not Found.

Exchange 2010 Web Services are now based on Windows Communication Foundation (WCF). You receive a HTTP 404 because WCF attempts to locate the endpoint for HTTP but cannot find it and throws a System.ServiceModel.EndpointNotFoundException exception which bubbles up to the client as a 404. I can't say that this is an intuitive error message but if you think about it long enough it kinda makes sense.

Using HTTP instead of HTTPS is not the recommended approach for Exchange Web Services but sometimes it is helpful in debugging / troubleshooting to have this option.  Therefore, if you need to enable HTTP do the following (Note: Please proceed with care, a misspelling here could be the difference between working and non-working):

  1. Confirm that you have unchecked the box 'Require SSL' in IIS. 
  2. Navigate to the EWS directory.  By default, C:\Program Files\Microsoft\Exchange Server\V14\ClientAccess\exchweb\ews
  3. Find the web.config file, copy it and rename the copy to web.config.old.
  4. Open the web.config in your favorite text editor.
  5. Replace the element:

    <endpoint address="" binding="customBinding" bindingConfiguration="EWSHttpsBinding"

     contract="Microsoft.Exchange.Services.Wcf.IEWSContract" />

With the following elements:

     <!-- Standard EWS HTTP endpoint-->

    <endpoint address="" binding="customBinding" bindingConfiguration="EWSHttpBinding"

     contract="Microsoft.Exchange.Services.Wcf.IEWSContract" />

     <!-- Standard EWS HTTPS endpoint -->

     <endpoint address="" binding="customBinding" bindingConfiguration="EWSHttpsBinding"

      contract="Microsoft.Exchange.Services.Wcf.IEWSContract" />

  1. Replace the element:

    <binding name="EWSHttpsBinding">

     <EWSMessageEncoderSoap11Element />

     <httpsTransport maxReceivedMessageSize="13600000" authenticationScheme="Anonymous"

      maxBufferSize="81920" transferMode="Streamed" />

    </binding>

With the following elements:

     <!-- EWS endpoint binding for HTTP -->

     <binding name="EWSHttpBinding">

       <EWSMessageEncoderSoap11Element />

       <httpTransport maxReceivedMessageSize="13600000" authenticationScheme="Anonymous"

        maxBufferSize="81920" transferMode="Streamed">

       </httpTransport>

     </binding>

     <!-- EWS endpoint binding for HTTPS-->

     <binding name="EWSHttpsBinding">

     <EWSMessageEncoderSoap11Element />

      <httpsTransport maxReceivedMessageSize="13600000" authenticationScheme="Anonymous"

       maxBufferSize="81920" transferMode="Streamed" >

      </httpsTransport>

    </binding>

  1. Save the file

At this point IIS should detect the change in the web.config and reload the settings.  Exchange 2010 SP1 should enable the behavior as it was in Exchange 2007. 

Note: If you forget that the setting 'Require SSL' is disabled in IIS than enable again it will cause your application to quit working. You will see Internal 500 errors as well as event log entries in the Event log on the Client Access Server. Here is an example of one:

Log Name:      Application
Source:        System.ServiceModel 3.0.0.0
Event ID:      3
Task Category: WebHost
Level:         Error
Keywords:      Classic
Description:
WebHost failed to process a request.
 Sender Information: System.ServiceModel.ServiceHostingEnvironment+HostingManager/27717712
 Exception: System.ServiceModel.ServiceActivationException: The service '/EWS/exchange.asmx' cannot be activated due to an exception during compilation.  The exception message is: Could not find a base address that matches scheme http for the endpoint with binding CustomBinding. Registered base address schemes are [https].. ---> System.InvalidOperationException: Could not find a base address that matches scheme http for the endpoint with binding CustomBinding. Registered base address schemes are [https].
   at System.ServiceModel.ServiceHostBase.MakeAbsoluteUri(Uri relativeOrAbsoluteUri, Binding binding, UriSchemeKeyedCollection baseAddresses)
   at System.ServiceModel.Description.ConfigLoader.LoadServiceDescription(ServiceHostBase host, ServiceDescription description, ServiceElement serviceElement, Action`1 addBaseAddress)
   at System.ServiceModel.ServiceHostBase.ApplyConfiguration()
   at System.ServiceModel.ServiceHostBase.InitializeDescription(UriSchemeKeyedCollection baseAddresses)
   at System.ServiceModel.ServiceHost..ctor(Type serviceType, Uri[] baseAddresses)
   at System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(Type serviceType, Uri[] baseAddresses)
   at System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses)
   at System.ServiceModel.ServiceHostingEnvironment.HostingManager.CreateService(String normalizedVirtualPath)
   at System.ServiceModel.ServiceHostingEnvironment.HostingManager.ActivateService(String normalizedVirtualPath)
   at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath)
   --- End of inner exception stack trace ---
   at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath)
   at System.ServiceModel.ServiceHostingEnvironment.EnsureServiceAvailableFast(String relativeVirtualPath)
 Process Name: w3wp
 Process ID: 1234

If you would like to enable 'Require SSL' again on the EWS virtual directory please follow the instructions below:  

  1. Check the box 'Require SSL' on the EWS virtual directory in IIS. Check the 'Require 128-bit SSL box as appropriate. 

  2. Rename the current web.config to web.config.HTTP to create a backup

  3. If you still have the old Web.Config change the name of it from web.config.old back to web.config.  If not, continue to Step 4.

  4. Remove the element:

         <!-- Standard EWS HTTP endpoint-->

        <endpoint address="" binding="customBinding" bindingConfiguration="EWSHttpBinding"

         contract="Microsoft.Exchange.Services.Wcf.IEWSContract" />

  5. Remove the following element:

     <!-- EWS endpoint binding for HTTP -->

     <binding name="EWSHttpBinding">

       <EWSMessageEncoderSoap11Element />

       <httpTransport maxReceivedMessageSize="13600000" authenticationScheme="Anonymous"

        maxBufferSize="81920" transferMode="Streamed">

       </httpTransport>

     </binding>

  1. Save the file