Troubleshooting IIS Compression issues in IIS 6 or IIS 7.x
Applies to: Internet Information Services 6.0, Internet Information Services 7.0 and later versions
Overview
Enabling HTTP Compression for your IIS 6 or 7 web applications is one way of increasing site performance.
Many of the compression properties required to completely manage IIS are not exposed by the admin GUI. It merely offers an on or off switch. So, to completely enable HTTP compression, you must use a tool other than the IIS Manager to update the metabase.xml file. The most common tool used is adsutil.vbs, which is included in the IIS installation directory.
This article helps you to configure compression and identifies common reasons of why IIS compression may not work in IIS 6 and IIS 7.x.
Tools used in this troubleshooter
- Fiddler
- Process Monitor
- Metabase ACL
- IIS 7 FREB trace
Verification
Determine if compression is working
The only way to determine whether the IIS server sent a compressed response is by analyzing a network trace of the client request and server response. The request from the client must contain the following HTTP Request Header:
HTTP: Accept-Encoding =gzip, deflate
This lets the server know that the client is willing to receive a compressed response and supports compression. In return, a compressed response from the server will contain the following HTTP Response header and a value:
HTTP: Content-Encoding = gzip
The following screenshots show output from the Fiddler tool when compression isn't working:
Troubleshooting compression issues
Perform the following steps to troubleshoot compression issues:
Enable Compression in IIS 6 or IIS 7.
From the IIS Manager, right-click on the Web Sites node, select Properties, and then select Services.
Specify compression folder and permissions.
IIS stores compressed files in a folder, which can be configured. By default, it's
%windir%\IIS Temporary Compressed Files
for IIS 6, and%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files
for IIS 7.IIS_WPG(IIS_IURS for IIS 7) must have full control permission for this folder. Use Process Monitor to troubleshoot this type of a permission issue.
Check if compression is enabled in Metabase.xml.
Compression isn't turned on in the metabase at the right nodes. There are three metabase nodes for the Compression configuration:
w3svc/filters/compression/parameters
w3svc/filters/compression/gzip
w3svc/filters/compression/deflate
Configuring the
/parameters
node is mandatory. Then, you can configure either/gzip
or/deflate
node, or both. This means that configuring just the gzip, deflate, or parameters nodes will not work. If you configure the/parameters
and/gzip
nodes, the Gzip compression scheme will be enabled. If you configure the/parameters
and/deflate
nodes, the Deflate compression scheme will be enabled. Finally, if you configure all three nodes, both GZip compression and Deflate compression will be enabled.Check the metabase permission for IIS 6.
By default,
IIS_WPG
has Read, Unsecure Read, Enumerate Keys, and Write permissions to the/LM/W3SVC/Filters
.IIS will be unable to initialize the compression if the permissions were removed due to unexpected change or if security hardens.
Use metaacl.vbs to verify and modify IIS 6 metabase ACL. For more information, see Default Metabase ACL.
If the application pool identity (or the
IIS_WPG
group in general) doesn't have Read and Write access to the metabase key W3SVC or Filters, a failure condition ofCOMPRESSION_DISABLED
will be logged in an Enterprise Tracing for Windows (ETW) trace.ETW Trace
IISCompression: STATIC_COMPRESSION_NOT_SUCCESS - IIS has been unsuccessful doing static compression Reason: COMPRESSION_DISABLED
Check if dynamic or static compression is turned off in Metabase.xml.
At each of the three configuration nodes (
/parameters
,/gzip
, and/deflate
), you have the option of enabling static and/or dynamic compression. To enable static compression for file types such as .txt and .html, you must set theHcDoStaticCompression
key to1
(orTRUE
). To enable dynamic compression for file types such as .asp, .aspx, .asmx, or .exe, you must set theHcDoDynamicCompression
key to1
(orTRUE
).For example, to set dynamic compression at the
/parameters
node, run the following command by using adsutil.vbs:cscript.exe adsutil.vbs SET w3svc/filters/compression/parameters/HcDoDynamicCompression TRUE
The output of the previous command looks like this:
HcDoDynamicCompression : (BOOLEAN) True
In IIS7
<system.webServer> <urlCompression doStaticCompression="true" doDynamicCompression="true" /> </system.webServer>
Check if the file type you want to compress is listed in the appropriate File Extensions sections at the
/gzip
and/deflate
nodes.After you turn on compression with the
HcDoDynamicCompression
and/orHcDoStaticCompression
keys, specify which file types must be actually compressed. By default, STATIC compression uses file types such as .htm, .html, and .txt and DYNAMIC compression uses .asp, .dll, and .exe. If you want to compress different file types, for example .aspx, add it to the appropriate file extension section in the/gzip
and-or/deflate
nodes, depending on the type of compression you're using. For static file compression (like .html, txt, and xml), add the file extensions to theHcFileExtensions
property. For dynamic compression (like .asp, .aspx, and .asmx) add it to theHcScriptFileExtension
property.For static files
adsutil.vbs SET w3svc/filters/compression/gzip/HcFileExtensions "htm" "html" "txt"
adsutil.vbs GET w3svc/filters/compression/gzip/HcFileExtensions
The previous command shows the following output:
HcFileExtensions : (LIST) (3 Items) "htm" "html" "txt"
For dynamic files
adsutil.vbs SET w3svc/filters/compression/gzip/HcScriptFileExtensions "asp" "dll" "exe" "aspx" adsutil.vbs get w3svc/filters/compression/gzip/HcScriptFileExtensions
The previous command shows the following output:
HcFileExtensions : (LIST) (4 Items) "asp" "dll" "exe" "aspx"
In IIS7
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files" minFileSizeForComp="1000"> <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" /> <staticTypes> <add mimeType="text/*" enabled="true" /> <add mimeType="message/*" enabled="true" /> <add mimeType="application/x-javascript" enabled="true" /> <add mimeType="application/atom+xml" enabled="true" /> <add mimeType="application/xaml+xml" enabled="true" /> <add mimeType="*/*" enabled="false" /> </staticTypes> <dynamicTypes> <add mimeType="text/*" enabled="true" /> <add mimeType="message/*" enabled="true" /> <add mimeType="application/x-javascript" enabled="true" /> <add mimeType="*/*" enabled="false" /> </dynamicTypes> </httpCompression> <system.web.extensions> <scripting> <scriptResourceHandler enableCompression="false" /> </scripting> </system.web.extensions>
Note
You must configure the
HcFileExtensions
orHcScriptFileExtensions
properties with the correct syntax. Any trailing spaces or unnecessary quotes or carriage returns will cause the property to be misconfigured. Unfortunately, adsutil.vbs doesn't show an error if you add an extra space, so you need to be very careful. Also, you can't copy or paste the values into a command prompt or into the metabase.xml file (metabase direct-edit) and must type it manually.Check if compression is set at the master level, but is getting overridden by a setting at a child level.
Compression would be enabled at the
w3svc/filters/compression
level. However, it might be that it's getting overridden by a setting at the website or application level.For example, if you have
HcDoDynamicCompression
set toTRUE
at thew3svc/filters/compression
level, and for the default website haveDoDynamicCompression
set toFALSE
, dynamic compression will not occur for responses to requests for the default website.Check if an anti-virus program has scanned the directory where the compressed files are saved.
When compression is enabled on a server running IIS and an HTTP request is served from the IIS compression directory, a 0-byte file might be returned instead of the expected file.
Note
You may only see these symptoms if HTTP Static Compression is enabled.
This happens because an antivirus software running on the IIS server is scanning the IIS compression directory.
So, you would need to exclude the IIS compression directory from the antivirus software's scan list.
Check if the URL being requested contains a slash as part of the parameters passed to the executing DLL file.
Check if the ISAPI filters modify the request or response headers.
An ISAPI is doing the send operation and isn't sending the complete set of HTTP headers along with the entity to
HTTP_COMPRESSION::DoDynamicCompression
. SinceDoDynamicCompression
doesn't receive all the data from the ISAPI, we can't compress the response. Third party and/or non-Microsoft ISAPIs have been seen to do this by putting the headers in the function meant for the entity body or the entity body in the function meant for the HTTP headers, or by not providing any headers. When this happens, things like the ISAPI filter SF_NOTIFY_SEND_RESPONSE, or AddResponseHeaders, or dynamic compression will fail. The ISAPI needs to put the headers and the entity in the right locations, respectively.Check if the response status code is something other than 200. In IIS 6 or 7, only responses with an HTTP 200 status will get compressed.
Response with status codes other than 200 will not be compressed. You have to write an
HTTPModule
to achieve the same.Check if the request contains a
Via: header
, theVia headers
indicates that the request is coming to IIS through a proxy.Many proxies don't handle the compression header correctly and provide compressed data to clients when they aren't supposed to. So, by default, the compressed responses aren't allowed when the request has a Via header. You can override this by setting the
HcNoCompressionForProxies
metabase key toTrue
.Check if the request is for a static page, and the response contains document footer. Document footers will cause static compression to fail.
Check if the static compression isn't working. This may happen if you have a wildcard application mapping installed at the root level in IIS. For example, we have application mappings for the .html or .txt extensions on the server and this will make IIS consider your requests to .txt as dynamic requests instead of static and since .txt isn't an extension in the dynamic compression list, it doesn't get compressed.
Check if the IIS Compression and
Accept-Encoding: identity
field is present.Per RFC2616, if an
Accept-Encoding
field is present in a request and if the server can't send a response, which is acceptable according to theAccept-Encoding
header, then the server should send an error response with the 406 (Not Acceptable) status code. If noAccept-Encoding
field is present in a request, the server might assume that the client will accept any content coding. In this case, if "identity" is one of the available content codes, then the server should use the "identity" content code, unless it has additional information that a different content-code is meaningful to the client.Check if you are using ETW trace to troubleshoot IIS compression issue.
Event Tracing for Windows (ETW) is a feature of the Windows OS that allows you to troubleshoot issues with HTTP requests.
Here are the steps to troubleshooting IIS compression issue.
Create a text file named IISProviders.txt and put follow content into the file."IIS: WWW Server" is the provider name, 0xFFFFFFFE means trace for all events, and 5 means verbose level.
Open a command prompt, and run the following command.
logman start trace compressionTrace -pf IISProviders.txt -ets
Reproduce the problem.
Run the following command to stop the trace.
logman stop trace compressionTrace -ets
Convert the trace to text file.
Trace report converts the binary trace data into text and produces two files in the directory where you executed the
tracerpt
command:tracerpt compressionTrace.etl
Summary.txt contains general details about the trace session, including which providers were used.
DumpFile.csv contains the actual trace data in a text format.
Read the trace file to find useful information. Open the dumpfile.csv, and find keyword like COMPRESSION_NOT_SUCCESS. Here's an example:
IISCompression, STATIC_COMPRESSION_NOT_SUCCESS, 0x000008B0, 129744354075770195, 0, 0, {00000000-0000-0000-0700-0060000000bd}, "NO_MATCHING_SCHEME", 0, 0
This error NO_MATCHING_SCHEME means that there weren't compression scheme matches for this extension or Accept-Encoding. For a detailed list of compression errors, see the List of compression errors.
Check if the FREB trace to troubleshooting IIS compression issue is used.
For detailed steps, see Troubleshooting Failed Requests Using Tracing in IIS 7.
Here's an example of using IIS 7 FREB trace to troubleshoot compression issues.
List of compression errors
For a detailed list of compression errors, see the following table.
Note
The following reasons apply to both IIS 6 and IIS 7.
Reason | Description |
---|---|
NO_ACCEPT_ENCODING | No Accept-Encoding sent by client. |
COMPRESSION_DISABLED | compression is disabled because no suitable configuration was found. |
NO_COMPRESSION_10 | Server not configured to compress 1.0 requests. |
NO_COMPRESSION_PROXY | Server not configured to compress proxy requests. |
NO_MATCHING_SCHEME | No compression scheme matches for this extension/Accept-Encoding. |
UNKNOWN_ERROR | Unknown error. |
NO_COMPRESSION_RANGE | Server not configured to compress range requests |
FILE_TOO_SMALL | File smaller than compression threshold. |
FILE_ENCRYPTED | File encrypted. |
COMPRESS_FILE_NOT_FOUND | Compressed copy does not exist. |
COMPRESS_FILE_STALE | Compressed copy out of date. |
NO_MATCHING_CONTENT_TYPE | Server not configured to compress content-Type for this extension. |
HEADERS_SENT_TWICE | Headers being sent twice for the same response. |
NO_HEADER_SENT | No Headers sent before entity body send. |
NOT_SUCCESS_STATUS | The response status code is not successful (200). |
ALREADY_CONTENT_ENCODING | There is a content-encoding already present in the response. |
Note
The following reasons apply to IIS 7 only.
Reason | Description |
---|---|
FOOTER_ENABLED | Document footer enabled for static files. |
NOT_FREQUENTLY_HIT | URL hasn't been requested frequently enough to justify compression. |
FAIL_TO_COMPRESS | Compressed copy couldn't be created. |