Caddy update wiped to defaults, no permission to write new configs

1. The problem I’m having:

My Caddy install has stopped listening on port 443, and thus redirecting http → https after updating to the latest version.

I believe I accidentally overwrote the install at the wrong file location (var/lib/caddy; instead of /usr/bin/caddy). Either this has reset the config, or the update to Caddy v2 has changes which have led to the caddy server no longer listening on port 443. While I was able to get it working again on the http port, the caddy logs declare “server is not listening on port 443”.

I have checked with my ISP, and confirmed that my router is also both open and pointing 443 to Caddy. DNS addresses are set correctly.

Curl output shows the site is working (I am finally learning how to properly troubleshoot thanks to the team’s patience and help here! :grin:)

* Host domain1.net:80 was resolved.
* IPv6: IPv6
* IPv4: IPv4
*   Trying [IPv6]:80...
*   Trying IPv4:80...
* Connected to domain1.net (IPv4) port 80
> GET / HTTP/1.1
> Host: domain.net
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/1.1 302 Found
< Content-Length: 0
< Date: Fri, 24 Jan 2025 01:05:43 GMT
< Location: web/
< Server: Caddy
< Server: Kestrel
< 
* Connection #0 to host domain1.net left intact

2. Error messages and/or full log output:

Jan 23 23:17:48 caddy[10068]: caddy.HomeDir=/var/lib/caddy
Jan 23 23:17:48 caddy[10068]: caddy.AppDataDir=/var/lib/caddy/.local/share/caddy
Jan 23 23:17:48 caddy[10068]: caddy.AppConfigDir=/var/lib/caddy/.config/caddy
Jan 23 23:17:48 caddy[10068]: caddy.ConfigAutosavePath=/var/lib/caddy/.config/caddy/autosave.json
Jan 23 23:17:48 caddy[10068]: caddy.Version=v2.9.1 h1:OEYiZ7DbCzAWVb6TNEkjRcSCRGHVoZsJinoDR/n9oaY=
Jan 23 23:17:48 caddy[10068]: runtime.GOOS=linux
Jan 23 23:17:48 caddy[10068]: runtime.GOARCH=amd64
Jan 23 23:17:48 caddy[10068]: runtime.Compiler=gc
Jan 23 23:17:48 caddy[10068]: runtime.NumCPU=12
Jan 23 23:17:48 caddy[10068]: runtime.GOMAXPROCS=12
Jan 23 23:17:48 caddy[10068]: runtime.Version=go1.23.4
Jan 23 23:17:48 caddy[10068]: os.Getwd=/
Jan 23 23:17:48 caddy[10068]: LANG=en_AU.UTF-8
Jan 23 23:17:48 caddy[10068]: LANGUAGE=en_AU:en
Jan 23 23:17:48 caddy[10068]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/snap/bin
Jan 23 23:17:48 caddy[10068]: NOTIFY_SOCKET=/run/systemd/notify
Jan 23 23:17:48 caddy[10068]: USER=caddy
Jan 23 23:17:48 caddy[10068]: LOGNAME=caddy
Jan 23 23:17:48 caddy[10068]: HOME=/var/lib/caddy
Jan 23 23:17:48 caddy[10068]: INVOCATION_ID=1ddcb4740dfb493f88ce442d38cc0294
Jan 23 23:17:48 caddy[10068]: JOURNAL_STREAM=8:64795
Jan 23 23:17:48 caddy[10068]: SYSTEMD_EXEC_PID=10068
Jan 23 23:17:48 caddy[10068]: MEMORY_PRESSURE_WATCH=/sys/fs/cgroup/system.slice/caddy.service/memory.pressure
Jan 23 23:17:48 caddy[10068]: MEMORY_PRESSURE_WRITE=c29tZSAyMDAwMDAgMjAwMDAwMAA=
Jan 23 23:17:48 caddy[10068]: CF_API_TOKEN=removed
Jan 23 23:17:48 caddy[10068]: CF_API_TOKEN_2=removed
Jan 23 23:17:48 caddy[10068]: {"level":"info","ts":1737634668.1645226,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Jan 23 23:17:48 caddy[10068]: {"level":"info","ts":1737634668.1654692,"msg":"adapted config to JSON","adapter":"caddyfile"}
Jan 23 23:17:48 caddy[10068]: {"level":"info","ts":1737634668.1660628,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//[::1]:2019","//127.0.0.1:2019","//localhost:2019"]}
Jan 23 23:17:48 caddy[10068]: {"level":"warn","ts":1737634668.166145,"logger":"http.auto_https","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server","server_name":"srv0","http_port":80}
Jan 23 23:17:48 caddy[10068]: {"level":"info","ts":1737634668.1662474,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0000ed300"}
Jan 23 23:17:48 calcifer caddy[10068]: {"level":"warn","ts":1737634668.1664176,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
Jan 23 23:17:48  caddy[10068]: {"level":"warn","ts":1737634668.1664236,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
Jan 23 23:17:48 caddy[10068]: {"level":"info","ts":1737634668.1664252,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
Jan 23 23:17:48 caddy[10068]: {"level":"error","ts":1737634668.166443,"msg":"unable to create folder for config autosave","dir":"/var/lib/caddy/.config/caddy","error":"mkdir /var/lib/caddy: not a directory"}
Jan 23 23:17:48 calcifer caddy[10068]: {"level":"warn","ts":1737634668.1664574,"logger":"tls","msg":"unable to get instance ID; storage clean stamps will be incomplete","error":"open /var/lib/caddy/.local/share/caddy/instance.uuid: not a directory"}
Jan 23 23:17:48 calcifer caddy[10068]: {"level":"info","ts":1737634668.1664624,"msg":"serving initial configuration"}
Jan 23 23:17:48 calcifer caddy[10068]: {"level":"error","ts":1737634668.166515,"logger":"tls","msg":"could not clean default/global storage","error":"unable to acquire storage_clean lock: creating lock file: open /var/lib/caddy/.local/share/caddy/locks/storage_clean.lock: not a directory"}
Jan 23 23:17:48 calcifer caddy[10068]: {"level":"info","ts":1737634668.1665196,"logger":"tls","msg":"finished cleaning storage units"}
Jan 23 23:17:48 calcifer systemd[1]: Started caddy.service - Caddy.

3. Caddy version:

v2.9.1 h1:OEYiZ7DbCzAWVb6TNEkjRcSCRGHVoZsJinoDR/n9oaY=

4. How I installed and ran Caddy:

Run using systemctl commands.
Installed via downloading custom binary with cloudflare binary and moving to /var/lib/caddy. I also run chmod +x and chown caddy:caddy commands.

a. System environment:

Ubuntu 22.04.1 on Intel (amd64)

b. Command:

Caddy autoruns on startup. To reload I use

systemctl reload caddy

d. My complete Caddy config:

  GNU nano 7.2                                                              /etc/caddy/Caddyfile                                                                        
http://domain1.net {
        reverse_proxy IP1:8096
        tls {
                issuer acme {
                        dns cloudflare {env.CF_API_TOKEN}
                        resolvers 1.1.1.1
                        propagation_delay 60s
                        propagation_timeout -1
                }
        }
}

http://domain2.net {
        file_server
        encode zstd gzip

        header {
                Access-Control-Allow-Headers *
                Access-Control-Allow-Methods *
                Access-Control-Allow-Origin *
        }
        @options {
                method OPTIONS
        }
        respond @options 204

        reverse_proxy IP2:6789 {
                header_up Host IP2:6789
        }
        tls {
                issuer acme {
                        dns cloudflare {env.CF_API_TOKEN_2}
                        resolvers 1.1.1.1
                        propagation_delay 60s
                        propagation_timeout -1
                }
        }
}

5. Links to relevant resources:

As you can see above, the logs are showing that caddy is failing to write to /var/lib/caddy. I am really perplexed by this. So far to attempt to fix I have tried:

  1. Uninstalling caddy and reinstalling apt remove caddy | apt install caddy
  2. Removing /usr/bin/caddy, /var/lib/caddy, replacing them with the custom binary
  3. Running chmod, chown commands; i.e. sudo chmod +x /var/lib/caddy | sudo chown caddy:caddy /var/lib/caddy
  4. Running validation on the Caddyfile and reloading, i.e. sudo caddy fmt /etc/caddy/Caddyfile --overwrite
  5. Manually deleting and then creating the folder caddy is unable to write to manually, using sudo rm and then sudo mkdir commands.
  6. Running chmod and chown commands on the newly created directories; i.e. sudo chown caddy:caddy /var/lib/caddy/.config/caddy and sudo chmod 655 /var/lib/caddy/.config/caddy

Still, the caddy logs output remains identical:

Jan 24 13:12:05 caddy[149564]: {"level":"info","ts":1737684725.9312725,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Jan 24 13:12:05 caddy[149564]: {"level":"info","ts":1737684725.9321814,"msg":"adapted config to JSON","adapter":"caddyfile"}
Jan 24 13:12:05 caddy[147371]: {"level":"info","ts":1737684725.9326262,"logger":"admin.api","msg":"received request","method":"POST","host":"localhost:2019","uri":"/load","remote_ip":"127.0.0.1","remote_port":"41890","headers":{"Accept-Encoding":["gzip"],"Cache-Control":["must-revalidate"],"Content-Length":["895"],"Content-Type":["application/json"],"Origin":["http://localhost:2019"],"User-Agent":["Go-http-client/1.1"]}}
Jan 24 13:12:05 caddy[147371]: {"level":"info","ts":1737684725.9331326,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//127.0.0.1:2019","//localhost:2019","//[::1]:2019"]}
Jan 24 13:12:05 caddy[147371]: {"level":"warn","ts":1737684725.9332042,"logger":"http.auto_https","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server","server_name":"srv0","http_port":80}
Jan 24 13:12:05 caddy[147371]: {"level":"warn","ts":1737684725.9334998,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
Jan 24 13:12:05 caddy[147371]: {"level":"warn","ts":1737684725.933508,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
Jan 24 13:12:05 caddy[147371]: {"level":"info","ts":1737684725.9335098,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
Jan 24 13:12:05 caddy[147371]: {"level":"info","ts":1737684725.9335175,"logger":"http","msg":"servers shutting down with eternal grace period"}
Jan 24 13:12:05 caddy[147371]: {"level":"error","ts":1737684725.9335856,"msg":"unable to create folder for config autosave","dir":"/var/lib/caddy/.config/caddy","error":"mkdir /var/lib/caddy/.config: permission denied"}
Jan 24 13:12:05 caddy[147371]: {"level":"info","ts":1737684725.9336333,"logger":"admin.api","msg":"load complete"}
Jan 24 13:12:05 caddy[147371]: {"level":"info","ts":1737684725.9346943,"logger":"admin","msg":"stopped previous server","address":"localhost:2019"}
Jan 24 13:12:05 systemd[1]: Reloaded caddy.service - Caddy.

When I check the user of caddy, it seems to be fine?:

systemctl show -pUser,UID caddy
UID=999
User=caddy

It seems like you’ve put your binary at /var/lib/caddy but also configured that as the directory for caddy’s data files. It’s trying to make that directory but finding that is already exists as a file (the binary).

The binary shouldn’t be in /var/lib. /usr/local/bin would be the obvious place.

Hia, thanks for your reply.

That makes sense, thanks for clarifying (I’m still learning how to use linux, so these path names and their uses aren’t always apparent).

Based on your info, I recursively removed the binary in var/lib

sudo rm -R /var/lib/caddy

Unfortunately, after reloading caddy nothing has changed. I then tried to manually create the folders:

$ sudo mkdir /var/lib/caddy
$ sudo mkdir /var/lib/caddy/.config
$ sudo mkdir /var/lib/caddy/.config/caddy

and then recursively apply the permissions and ownership to the folder:

$ sudo chown -R caddy:caddy /var/lib/caddy
$ sudo chmod -R 655 /var/lib/caddy

However this also seems to not have made a difference:

Jan 24 13:12:05 systemd[1]: Reloaded caddy.service - Caddy.
Jan 24 14:11:24 systemd[1]: Reloading caddy.service - Caddy...
Jan 24 14:11:24 caddy[150592]: {"level":"info","ts":1737688284.7485764,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Jan 24 14:11:24 caddy[150592]: {"level":"info","ts":1737688284.749488,"msg":"adapted config to JSON","adapter":"caddyfile"}
Jan 24 14:11:24 caddy[147371]: {"level":"info","ts":1737688284.7499259,"logger":"admin.api","msg":"received request","method":"POST","host":"localhost:2019","uri":"/load","remote_ip":"127.0.0.1","remote_port":"39182","headers":{"Accept-Encoding":["gzip"],"Cache-Control":["must-revalidate"],"Content-Length":["895"],"Content-Type":["application/json"],"Origin":["http://localhost:2019"],"User-Agent":["Go-http-client/1.1"]}}
Jan 24 14:11:24 caddy[147371]: {"level":"info","ts":1737688284.7503772,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//[::1]:2019","//127.0.0.1:2019","//localhost:2019"]}
Jan 24 14:11:24 caddy[147371]: {"level":"warn","ts":1737688284.750449,"logger":"http.auto_https","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server","server_name":"srv0","http_port":80}
Jan 24 14:11:24 caddy[147371]: {"level":"warn","ts":1737688284.7506742,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
Jan 24 14:11:24 caddy[147371]: {"level":"warn","ts":1737688284.7506802,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
Jan 24 14:11:24 caddy[147371]: {"level":"info","ts":1737688284.7506828,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
Jan 24 14:11:24 caddy[147371]: {"level":"info","ts":1737688284.7506895,"logger":"http","msg":"servers shutting down with eternal grace period"}
Jan 24 14:11:24 caddy[147371]: {"level":"error","ts":1737688284.750775,"msg":"unable to create folder for config autosave","dir":"/var/lib/caddy/.config/caddy","error":"mkdir /var/lib/caddy: permission denied"}
Jan 24 14:11:24 caddy[147371]: {"level":"info","ts":1737688284.7508142,"logger":"admin.api","msg":"load complete"}
Jan 24 14:11:24 caddy[147371]: {"level":"info","ts":1737688284.7518697,"logger":"admin","msg":"stopped previous server","address":"localhost:2019"}
Jan 24 14:11:24 systemd[1]: Reloaded caddy.service - Caddy.

Weirdly when i check the permissions it returns a readout I don’t understand:

$ ls -l /var/lib/caddy
total 0

ls -l doesn’t list the files that start with . by default. You need to add -a as well to list those.

caddy said it still has errors writing to that directory. What does ls -laR /var/lib/caddy say?

Ah yes, I forgot about that, thanks.

$ ls -laR /var/lib/caddy
/var/lib/caddy:
total 12
drw-r-xr-x  3 caddy caddy 4096 Jan 24 14:15 .
drwxr-xr-x 84 root  root  4096 Jan 24 14:15 ..
drw-r-xr-x  3 caddy caddy 4096 Jan 24 14:15 .config

/var/lib/caddy/.config:
total 12
drw-r-xr-x 3 caddy caddy 4096 Jan 24 14:15 .
drw-r-xr-x 3 caddy caddy 4096 Jan 24 14:15 ..
drw-r-xr-x 2 caddy caddy 4096 Jan 24 14:15 caddy

/var/lib/caddy/.config/caddy:
total 8
drw-r-xr-x 2 caddy caddy 4096 Jan 24 14:15 .
drw-r-xr-x 3 caddy caddy 4096 Jan 24 14:15 ..

Your directory permissions are messed up. The directories are all missing user execute permission (see drw-..., should be drwx...).

chmod -R +x /var/lib/caddy might be enough to fix it, as it looks like there are just the directories in there, no files.

Nice, thanks!
That seems to have at least fixed the folder permissions:

$ ls -laR /var/lib/caddy
/var/lib/caddy:
total 16
drwxr-xr-x  4 caddy caddy 4096 Jan 24 17:04 .
drwxr-xr-x 84 root  root  4096 Jan 24 14:15 ..
drwxr-xr-x  3 caddy caddy 4096 Jan 24 14:15 .config
drwx------  3 caddy caddy 4096 Jan 24 17:04 .local

/var/lib/caddy/.config:
total 12
drwxr-xr-x 3 caddy caddy 4096 Jan 24 14:15 .
drwxr-xr-x 4 caddy caddy 4096 Jan 24 17:04 ..
drwxr-xr-x 2 caddy caddy 4096 Jan 24 17:03 caddy

/var/lib/caddy/.config/caddy:
total 12
drwxr-xr-x 2 caddy caddy 4096 Jan 24 17:03 .
drwxr-xr-x 3 caddy caddy 4096 Jan 24 14:15 ..
-rw------- 1 caddy caddy  895 Jan 24 17:04 autosave.json
ls: cannot open directory '/var/lib/caddy/.local': Permission denied

Which also looks like it has fixed the the permission issues, I’m just not sure now how to fix the server not listening on port 443.

I know settings exist that allow me to manually tell the server to listen, but I’m unsure why the default setup that has always previously worked is no longer working?

Jan 24 17:12:21 systemd[1]: Reloading caddy.service - Caddy...
Jan 24 17:12:21 caddy[154599]: {"level":"info","ts":1737699141.5248272,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Jan 24 17:12:21 caddy[154599]: {"level":"info","ts":1737699141.5257308,"msg":"adapted config to JSON","adapter":"caddyfile"}
Jan 24 17:12:21 caddy[153335]: {"level":"info","ts":1737699141.526173,"logger":"admin.api","msg":"received request","method":"POST","host":"localhost:2019","uri":"/load","remote_ip":"127.0.0.1","remote_port":"40202","headers":{"Accept-Encoding":["gzip"],"Cache-Control":["must-revalidate"],"Content-Length":["895"],"Content-Type":["application/json"],"Origin":["http://localhost:2019"],"User-Agent":["Go-http-client/1.1"]}}
Jan 24 17:12:21 caddy[153335]: {"level":"info","ts":1737699141.5266829,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
Jan 24 17:12:21 caddy[153335]: {"level":"warn","ts":1737699141.526761,"logger":"http.auto_https","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server","server_name":"srv0","http_port":80}
Jan 24 17:12:21 caddy[153335]: {"level":"warn","ts":1737699141.5269947,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
Jan 24 17:12:21 caddy[153335]: {"level":"warn","ts":1737699141.5269997,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
Jan 24 17:12:21 caddy[153335]: {"level":"info","ts":1737699141.5270019,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
Jan 24 17:12:21 caddy[153335]: {"level":"info","ts":1737699141.5270066,"logger":"http","msg":"servers shutting down with eternal grace period"}
Jan 24 17:12:21 caddy[153335]: {"level":"info","ts":1737699141.5271149,"msg":"autosaved config (load with --resume flag)","file":"/var/lib/caddy/.config/caddy/autosave.json"}
Jan 24 17:12:21 caddy[153335]: {"level":"info","ts":1737699141.5271537,"logger":"admin.api","msg":"load complete"}
Jan 24 17:12:21 caddy[153335]: {"level":"info","ts":1737699141.528226,"logger":"admin","msg":"stopped previous server","address":"localhost:2019"}
Jan 24 17:12:21 systemd[1]: Reloaded caddy.service - Caddy.

Bump for issue unresolved

The sites configured in your Caddyfile are prefixed with http://. When done this way, Caddy will only listen on port 80. Remove that prefix.

Ah yep, that makes complete sense now, thankyou. That fixed the issue after a reset of the browser cache.

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