Per Yahoo's best practices for high performance web sites, I'd like to remove Etags from my headers (I'm manually managing all my caching and have no need for Etags... and when/if I need to scale to a farm, I'd really like them gone). I'm running IIS7 on Windows Server 2008. Anyone know how I can do this?
-
It works for IIS 8.0 onward at least as shown in the second answer of this post : http://stackoverflow.com/questions/7947420/iis-7-5-remove-etag-headers-from-response – RBT Jul 01 '16 at 03:14
12 Answers
Under IIS7 the Etag change number (the part of the Etag following : ) is always set to 0.
Hence the Etag from the server no longer varies from server to server for the same file and therefore the Yahoo best practice no longer really applies.
Since you can't actually suppress the ETag header on IIS7 it would probably be best that you don't fiddle with it at all. I've found by far the most useful configuration rule is "If the default doesn't break something, leave it alone".

- 187,081
- 35
- 232
- 306
-
2I'm tempted to kill etags for a different reason: Unless I'm misperceiving things, I'm seeing IIS on a *single server* gratuitously change the *first* component of etags (i.e. the so-called "Filetimestamp") despite my file not being modified. For example, the latest version of a file will be in the browser, the browser will send up 'If-None-Match: "01cc3a8acccc1:0"'/'If-Modified-Since: Fri, 06 Jan 2012 00:32:24 GMT', and IIS will respond with 'ETag: "b6baeea8acccc1:0"'/'Last-Modified: Fri, 06 Jan 2012 00:32:24 GMT'. These are js files w/ URLs like foo.js?rev=xxx, passing same xxx each time. – Chris Jan 06 '12 at 05:25
-
@Chris: I do very nearly the same thing, I allow js files to be cached and only change the xxx when the file is changed. I can't say that I've ever encountered the behaviour you are seeing on any version of IIS. Something is a bit odd with your IIS config I suspect. – AnthonyWJones Jan 06 '12 at 13:19
-
Thanks. As far as you know, is the "Filetimestamp" portion of etags based ONLY on the timestamp of the file being requested, and not on anything about the state of the machine/process/application? – Chris Jan 06 '12 at 22:49
-
@Chris: As far as I know yes E-Tag is based on the file time only. I've tried fiddling around with my server and I can't reproduce the problem you are seeing. – AnthonyWJones Jan 07 '12 at 19:51
-
I don't know that making a server non-modifiable is wise policy. Besides. I'm testing far-future Expires and I simply don't want an HTTP 304 response - ever. I want things to stay in a cache for a looooong time as I know those assets rarely change. There's lots of IETF documentation out there including the HTTP spec RFC 2616 that explains this can and should be done as a site administrator as that person will know their situation far better. Implementors are always looking for whats happening in the "wild". – Josh Robinson Nov 09 '17 at 18:23
You would think doing this in the web.config would work to disable ETags in IIS7. But sniffer trace confirms that ETag is sent down anyway.
<httpProtocol>
<customHeaders>
<remove name="ETag" />
</customHeaders>
</httpProtocol>
Using blank doesn't work, either. ETag is sent down anyway.
<httpProtocol>
<customHeaders>
<add name="ETag" value="" />
</customHeaders>
</httpProtocol>
Setting the ETag to blank quotes as other sites have suggested doesn't work.
<httpProtocol>
<customHeaders>
<add name="ETag" value="""" />
</customHeaders>
</httpProtocol>
Causes even more ETag to be sent down:
ETag: "8ee1ce1acf18ca1:0",""
In conclusion, nothing I can try or think of works to kill ETag on IIS7, at least without writing custom modules, etc.

- 63,320
- 48
- 150
- 153
-
2I've not confirmed this Jeff, but could this be because the httpProtocol section is locked at the website level. I found this the case when i was trying to programattically set the iis7 *compression* level via the web.config file. I had to finally *unlock* that section on the root server level. Maybe this section has the same problem? (I really wish ALL IIS settings were available via the GUI) – Pure.Krome Aug 25 '09 at 07:51
-
1@Pure.Krome: The unlock, combined with Jeff's second attempt above, seems to work for me in most cases... except (of course!) for image content. :-\
-
-
1
-
1Where all other solutions failed or were not feasible to implement for me, a simple rewrite rule worked. See my answer: http://stackoverflow.com/a/18025228/705198 – AndrewPK Aug 02 '13 at 20:33
-
not wanting to be pedantic, but this doesn't answer the question, its just gives examples of things that don't work. I can probably think of plenty of things that don't work... – Sam Holder Jun 30 '15 at 14:23
I wrote a custom http module to handle this. It's really not as bad as it sounds. Here's the code:
using System;
using System.Web;
namespace StrongNamespace.HttpModules
{
public class CustomHeaderModule : IHttpModule
{
public void Init(HttpApplication application)
{
application.PostReleaseRequestState += new EventHandler(application_PostReleaseRequestState);
}
public void Dispose()
{
}
void application_PostReleaseRequestState(object sender, EventArgs e)
{
HttpContext.Current.Response.Headers.Remove("Server");
HttpContext.Current.Response.Headers.Remove("X-AspNet-Version");
HttpContext.Current.Response.Headers.Remove("ETag");
}
}
}
Here's the web.config changes you'll want:
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By"/>
</customHeaders>
</httpProtocol>
<modules>
<add name="CustomHeaderModule" type="StrongNamespace.HttpModules.CustomHeaderModule"/>
</modules>
</system.webServer>
</configuration>

- 1,729
- 18
- 11
-
1+1, however this only appears to cover resources asked of the website, not things like favicons – Brad Jun 05 '14 at 02:41
I realize this is an old question, but I came across it while searching for a solution. I think I found a reasonable answer which I posted for this question.

- 1
- 1

- 4,023
- 1
- 23
- 18
UPDATE: added URL Rewrite Module requirement thanks to user @ChrisBarr
In iis 6 it's easy, you can add a custom header for 'ETag' = ""
In IIS 7, after reading this thread and figuring that it was impossible without using a custom http module, I found that you can simply install Microsoft's URL Rewrite module and add an outbound rewrite rule as follows:
<outboundRules>
<rule name="Remove ETag">
<match serverVariable="RESPONSE_ETag" pattern=".+" />
<action type="Rewrite" value="" />
</rule>
</outboundRules>
This actually works, and you don't need a custom http module (dll). Unlocking the system.webServer configuration section and setting customHeaders, etc., does not work - at least in all the cases I tried. A simple outbound rewrite rule does.

- 6,100
- 3
- 32
- 36
-
1This solution requires [this custom module](http://www.iis.net/downloads/microsoft/url-rewrite) to be installed in IIS though, correct? – Chris Barr Jul 15 '14 at 18:18
-
@ChrisBarr yes it does - sorry I failed to mention that. Answer updated. – AndrewPK Jul 16 '14 at 21:09
We had this problem, and even setting a blank custom ETag header in IIS 7 was not working for all files (for example image files). We ended up creating an HttpModule that explicitly removes the ETag header.

- 4,078
- 1
- 25
- 33
By the way, when you use iis8 it's simple
<element name="clientCache">
<attribute name="cacheControlMode" type="enum" defaultValue="NoControl">
<enum name="NoControl" value="0" />
<enum name="DisableCache" value="1" />
<enum name="UseMaxAge" value="2" />
<enum name="UseExpires" value="3" />
</attribute>
<attribute name="cacheControlMaxAge" type="timeSpan" defaultValue="1.00:00:00" />
<attribute name="httpExpires" type="string" />
<attribute name="cacheControlCustom" type="string" />
<attribute name="setEtag" type="bool" defaultValue="true" />
</element>
IIS 8.0: To use or not to use ETag

- 1,184
- 1
- 10
- 26
I Used the removeetag.dll
found on http://www.caspianit.co.uk/iis7-etag-problem/ and it worked perfectly.
hope it will work well for you too
Check out this blog post on how to completely remove the Etag http header in iis6,iis7 and iis7.5

- 29
- 2
-
2That requires a 3rd party plug in called Helicon Ape. Really we need a solution that uses the native IIS config, not an extra plug in. This is especially true for any large scale web farm, which is exactly where the ETag is the biggest problem. – Keith Jun 07 '10 at 15:17
http://www.jesscoburn.com/archives/2008/10/02/quickly-configure-or-disable-etags-in-iis7-or-iis6/ has a nice pictorial guide.
Essentially, you create a custom response header named ETag and make its value empty.

- 19,454
- 7
- 52
- 86
-
On IIS6, this only worked for me when I set no value not just two double quotes. i.e.
I think this will work .. I know remove and blank doesn't work.
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="ETag" value=" " />
</customHeaders>
</httpProtocol>
</configuration>
</system.webServer>

- 2,401
- 2
- 27
- 36
In IIS 7 you shouldn't have to worry about etags anymore as the IIS configuration number is always set to 0.
There is still a problem if you have IIS6 & IIS7 webservers in the same farm. In this case you would have to manually set the IIS6 config number to 0 as described in this article.
Etags are actually very useful as you don't need to change the filename like stack overflow does (i.e. default.css?1234). If you change the default.css file it will change the etag and therefore subsequent requests will get the file from the server and not the cache.

- 34,776
- 10
- 53
- 68
-
7far-forward expiration dates make ETags irrelevant, since the browser will literally never request the file again until the specified date (or until the filename changes, of course.) Thus, the need to remove it -- it's obsolete in that scenario. – Jeff Atwood Aug 09 '09 at 09:00
-
3@JeffAtwood not strictly true, the browser will request the file if the user hits the refresh button, if the etag is the same you get a 304 if diff you get a 200, the issue here is that you send down 2 headers where 1 would have been enough – Sam Saffron Mar 16 '12 at 03:07