Friday, December 14, 2012

Microsoft Internet Explorer 12152 errors..

IE has a 1 min keepalive timeout: http://support.microsoft.com/kb/813827

Apache2 has a default 5 second timeout: http://httpd.apache.org/docs/2.2/mod/core.html#keepalive

Therefore, Internet Explorer assumes the connection will close in a minute but Apache2 attempts to close after 5 seconds.  The problem is that if the connection is closed and the initial POST fails, Internet Explorer will only send the header but not the HTTP body.  Since the Apache2 server is expecting the rest of the data, eventually a timeout occurs and the 12xxx errors.

http://stackoverflow.com/questions/4796305/why-does-internet-explorer-not-send-http-post-body-on-ajax-call-after-failure

These patches exist in IE7-IE9, but they aren't by default activated.

This hotfix is included in Internet Explorer 7. However, the hotfix must still be enabled as described in the "How to enable this hotfix" section.

Internet Explorer 8

This hotfix is included in Internet Explorer 8. However, the hotfix must still be enabled as described in the "How to enable this hotfix" section.

Internet Explorer 9

This hotfix is included in Internet Explorer 9. However, the hotfix must still be enabled as described in the "How to enable this hotfix" section.

http://support.microsoft.com/kb/895954
http://support.microsoft.com/kb/831167/en-us

We could disable keepalive's for all Internet Explorer sessions, but here's one way using SetEnvIf in Apache 2.2 to accomplish it:

  # Remove after upgrading to Apache 2.4 and we can use SetEnvIfExpr instead of
  # this funky logic.
  #
  # Test by:
  # curl -v --user-agent 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/6.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; BRI/2;)' -H "X-Requested-With: XMLHttpRequest" -k 
  #
  # ...and all different combinations.
  #
  #  Based on: http://stephane.lesimple.fr/blog/2010-01-28/apache-logical-or-and-conditions-with-setenvif.html
  #
  # Logic below will disable keepalive's on Ajax-based IE browsers.  We may see a small performance
  # hit but better than random 12xxx Microsoft errors because of http://support.microsoft.com/kb/895954.
  # See http://stackoverflow.com/questions/4796305/why-does-internet-explorer-not-send-http-post-body-on-ajax-call-after-failure for
  # more context.
  #
  SetEnvIf User-Agent "^" disable_keepalive=0
  SetEnvIf User-Agent "MSIE [17-9]" disable_keepalive=1
  # Negative lookahead regexp matching.  If there is no Ajax XmlHttpRequest, we can invert
  # the flag that attempts to disable keepalive's.  Equivalent to performing an AND.
  SetEnvIf X-Requested-With "^(?!XMLHttpRequest).*" !disable_keepalive
  SetEnvIf disable_keepalive 1 nokeepalive downgrade-1.0 force-response-1.0
http://blogs.msdn.com/b/ieinternals/archive/2011/03/26/https-and-connection-close-is-your-apache-modssl-server-configuration-set-to-slow.aspx Also note that Apache2's default-ssl file has this configuration:
BrowserMatch "MSIE [2-6]" \
    nokeepalive ssl-unclean-shutdown \
    downgrade-1.0 force-response-1.0
# MSIE 7 and newer should be able to use keepalive
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown

(Yes, the MSIE [17-9] regex is correct https://bugs.launchpad.net/ubuntu/+source/apache2/+bug/626728)

 What does ssl-unclean-shutdown do?  It lists this information in /etc/default/sites-available/default-ssl:
#   SSL Protocol Adjustments:
#   The safe and default but still SSL/TLS standard compliant shutdown
#   approach is that mod_ssl sends the close notify alert but doesn't wait fo
#   the close notify alert from client. When you need a different shutdown
#   approach you can use one of the following variables:
#   o ssl-unclean-shutdown:
#     This forces an unclean shutdown when the connection is closed, i.e. no
#     SSL close notify alert is send or allowed to received.  This violates
#     the SSL/TLS standard but is needed for some brain-dead browsers. Use
#     this when you receive I/O errors because of the standard approach where
#     mod_ssl sends the close notify alert.
More details:
http://blogs.msdn.com/b/askie/archive/2009/06/18/change-in-behavior-with-internet-explorer-7-and-later-in-regard-to-connect-requests.aspx
https://groups.google.com/group/microsoft.public.winhttp/tree/browse_frm/month/2004-07/ee64525371504ef0?rnum=21&lnk=ol&pli=1\


Addnedum: The problem can often happen if you have load balancers that have a shorter timeout than the keepalive.  In this case, you may wish to increase your load balancer timeouts to be greater than IE Ajax timeouts.  If you adjust the load balancer timeouts, chances are you will see these 12xxxx errors disappear too.

2 comments:

  1. Seriously, thanks for the explanation.

    In Apache 2.4 and up, you can resolve this with one line

    ```
    # http://httpd.apache.org/docs/2.4/mod/mod_setenvif.html
    BrowserMatch MSIE KeepAlive 60
    ```

    ReplyDelete