Do not require .html extension Caddy v2

1. My Caddy version (caddy -version):


2. How I run Caddy:

a. System environment:

OS, relevant versions, systemd? docker? etc.
Linux Mint

b. Command:

./caddy run -config ./config.json 

c. Service/unit/compose file:


d. My complete config.json:

      "apps": {
        "http": {
          "servers": {
            "srv0": {
              "logs": {},
              "listen": [
              "routes": [
                  "match": [{"file": {"root": "./files/", "try_files": ["{path}" ,"{path}.html", "{path}index.html"]}}],
                  "handle": [
                      "handler": "encode"
                      "handler": "file_server",
                      "root": "./files/",
                      "pass_thru": false
        "tls": {
          "automation": {},
          "session_tickets": {}
      "logging": {
          "default": {
            "writer": {
              "output": "stdout"
            "level": "debug"

3. The problem I’m having:

I want to setup verys imple http server for html+js+css webiste. I want to user clean urls like:

/test instead of /test.html and /test_dir/ instad of /test_dir/index.html

With my config I can’t acces /test but all other url works fine.

4. Error messages and/or full log output:

2019/12/06 18:38:05.713	ERROR	http.log.access	handled request	{"request": {"method": "GET", "uri": "/favicon.ico", "proto": "HTTP/1.1", "remote_addr": "", "host": "", "headers": {"Accept": ["image/webp,*/*"], "Accept-Language": ["pl,en-US;q=0.7,en;q=0.3"], "Accept-Encoding": ["gzip, deflate"], "Connection": ["keep-alive"], "Pragma": ["no-cache"], "Cache-Control": ["no-cache"], "User-Agent": ["Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0"]}}, "common_log": " - - [06/Dec/2019:19:38:05 +0100] \"GET /favicon.ico HTTP/1.1\" 404 0", "latency": 0.000241749, "size": 0, "status": 404, "resp_headers": {"Server": ["Caddy"]}}

5. What I already tried:

6. Links to relevant resources:

Welcome @Behoston, and thanks for trying Caddy 2 while we’re still in beta!

You have a file matcher that is set up mostly correctly (although, I would get rid of "{path}index.html" at the end since the file server takes care of index files for you – at least, I think it should), but you have no logic that rewrites the request to the matched file.

You will need a rewrite handler:

    "handler": "rewrite",
    "uri": "{http.matchers.file.relative}{http.request.uri.query_string}"

This should internally rewrite the request from /test to /test.html (because {http.matchers.file.relative} == /test.html if test.html exists inside the root).

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