Caddy ipfilter downfile not getting served when gzip is enabled, browser downloads it instead

I’m trying to get Caddy to serve a simple .html page when an ip is not present in the ipfilter list within my Caddyfile, which looks like this: {

  errors {
        502     /etc/caddy/down.html

  proxy / {
    except /scripts /images
    policy ip_hash
    health_check /admin/pw.html
    health_check_interval 10s
    health_check_timeout 30s

  proxy /scripts {

  proxy /images {


  redir 301 {
    if {>X-Forwarded-Proto} is http
    / https://{host}{uri}

   ipfilter / {
     rule allow
     blockpage /etc/caddy/down.html

I have obfuscated the domain and the relevant IP addresses, but I hope you get the idea. When I try to access form an IP that is not or, my browser just downloads the html file as a Gzip archive.

How can I fix this, and what am I doing wrong?

EDIT: I just found that if I comment out the gzip config line, the blockpage is served correctly! So for now, I have gzip disabled, but how would I get blockpage and gzip to work together?

I forgot to include that I’m running Caddy 0.10.14 (non-commercial use only).

Hi @jonesnc,

The gzip directive operates early on in the middleware chain, but it simply swaps out the default ResponseWriter for a gzipWriter so anything written by later middleware such as ipfilter is compressed.

If you take a look at the ipfilter code handling blocked pages, it doesn’t look like a Content-Type header is set anywhere when the nominated block page is written. For an example of code that sets the Content-Type while returning a nominated HTML document, see this code in the built-in errors plugin.

When a browser receives a compressed file without a content type, it can’t make the assumption that it’s HTML intended to be rendered, so it downloads it instead. I’d wager that’s the cause of your problem.

You can open an issue on the pyed/ipfilter repository here: Issues · pyed/ipfilter · GitHub

Feel free to mention this forum post as a reference.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.