strconf.Atoi: parsing ";": invalid syntax

1. The problem I’m having:

I have a simple setup (not proxying, no custom modules) and i get an "strconv.Atoi: parsing \";\": invalid syntax" error, resulting in HTTP 500.

2. Error messages and/or full log output:

caddy# docker compose up
[+] Running 2/2
 ✔ Network caddy_default    Created                                                                               0.0s 
 ✔ Container caddy-caddy-1  Created                                                                               0.0s 
Attaching to caddy-1
caddy-1  | {"level":"info","ts":1745949936.7787268,"msg":"maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined"}
caddy-1  | {"level":"info","ts":1745949936.778841,"msg":"GOMEMLIMIT is updated","package":"github.com/KimMachineGun/automemlimit/memlimit","GOMEMLIMIT":7494370099,"previous":9223372036854775807}
caddy-1  | {"level":"info","ts":1745949936.7788763,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
caddy-1  | {"level":"info","ts":1745949936.7793455,"msg":"adapted config to JSON","adapter":"caddyfile"}
caddy-1  | {"level":"info","ts":1745949936.7799387,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//127.0.0.1:2019","//localhost:2019","//[::1]:2019"]}
caddy-1  | {"level":"info","ts":1745949936.7800715,"logger":"http.auto_https","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
caddy-1  | {"level":"info","ts":1745949936.7800872,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
caddy-1  | {"level":"info","ts":1745949936.7800875,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000604d80"}
caddy-1  | {"level":"info","ts":1745949936.7802484,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
caddy-1  | {"level":"info","ts":1745949936.7804575,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
caddy-1  | {"level":"warn","ts":1745949936.7805417,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
caddy-1  | {"level":"warn","ts":1745949936.7805586,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
caddy-1  | {"level":"info","ts":1745949936.780571,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
caddy-1  | {"level":"info","ts":1745949936.7805831,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["cloud.bunker496.de"]}
caddy-1  | {"level":"info","ts":1745949936.7846315,"logger":"tls","msg":"cleaning storage unit","storage":"FileStorage:/data/caddy"}
caddy-1  | {"level":"info","ts":1745949936.7855954,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
caddy-1  | {"level":"info","ts":1745949936.785631,"msg":"serving initial configuration"}
caddy-1  | {"level":"info","ts":1745949936.785652,"logger":"tls.obtain","msg":"acquiring lock","identifier":"cloud.bunker496.de"}
caddy-1  | {"level":"info","ts":1745949936.786231,"logger":"tls","msg":"finished cleaning storage units"}
caddy-1  | {"level":"info","ts":1745949936.7869432,"logger":"tls.obtain","msg":"lock acquired","identifier":"cloud.bunker496.de"}
caddy-1  | {"level":"info","ts":1745949936.7869918,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"cloud.bunker496.de"}
caddy-1  | {"level":"info","ts":1745949936.7873693,"logger":"http","msg":"creating new account because no account for configured email is known to us","email":"","ca":"https://acme-v02.api.letsencrypt.org/directory","error":"open /data/caddy/acme/acme-v02.api.letsencrypt.org-directory/users/default/default.json: no such file or directory"}
caddy-1  | {"level":"info","ts":1745949936.7873976,"logger":"http","msg":"ACME account has empty status; registering account with ACME server","contact":[],"location":""}
caddy-1  | {"level":"info","ts":1745949936.7895691,"logger":"http","msg":"creating new account because no account for configured email is known to us","email":"","ca":"https://acme-v02.api.letsencrypt.org/directory","error":"open /data/caddy/acme/acme-v02.api.letsencrypt.org-directory/users/default/default.json: no such file or directory"}
caddy-1  | {"level":"info","ts":1745949937.6754174,"logger":"http","msg":"new ACME account registered","contact":[],"status":"valid"}
caddy-1  | {"level":"info","ts":1745949937.6797798,"logger":"http","msg":"waiting on internal rate limiter","identifiers":["cloud.bunker496.de"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
caddy-1  | {"level":"info","ts":1745949937.6797962,"logger":"http","msg":"done waiting on internal rate limiter","identifiers":["cloud.bunker496.de"],"ca":"https://acme-v02.api.letsencrypt.org/directory","account":""}
caddy-1  | {"level":"info","ts":1745949937.6798203,"logger":"http","msg":"using ACME account","account_id":"https://acme-v02.api.letsencrypt.org/acme/acct/2369969697","account_contact":[]}
caddy-1  | {"level":"info","ts":1745949938.0695524,"msg":"trying to solve challenge","identifier":"cloud.bunker496.de","challenge_type":"tls-alpn-01","ca":"https://acme-v02.api.letsencrypt.org/directory"}
caddy-1  | {"level":"info","ts":1745949938.6904066,"logger":"tls","msg":"served key authentication certificate","server_name":"cloud.bunker496.de","challenge":"tls-alpn-01","remote":"23.178.112.103:56297","distributed":false}
caddy-1  | {"level":"info","ts":1745949938.9359486,"logger":"tls","msg":"served key authentication certificate","server_name":"cloud.bunker496.de","challenge":"tls-alpn-01","remote":"13.50.226.247:15104","distributed":false}
caddy-1  | {"level":"info","ts":1745949939.1071265,"logger":"tls","msg":"served key authentication certificate","server_name":"cloud.bunker496.de","challenge":"tls-alpn-01","remote":"3.149.231.253:35782","distributed":false}
caddy-1  | {"level":"info","ts":1745949939.214034,"logger":"tls","msg":"served key authentication certificate","server_name":"cloud.bunker496.de","challenge":"tls-alpn-01","remote":"34.216.76.230:10528","distributed":false}
caddy-1  | {"level":"info","ts":1745949939.227965,"logger":"tls","msg":"served key authentication certificate","server_name":"cloud.bunker496.de","challenge":"tls-alpn-01","remote":"13.212.46.212:63974","distributed":false}
caddy-1  | {"level":"info","ts":1745949940.3631442,"msg":"authorization finalized","identifier":"cloud.bunker496.de","authz_status":"valid"}
caddy-1  | {"level":"info","ts":1745949940.363166,"msg":"validations succeeded; finalizing order","order":"https://acme-v02.api.letsencrypt.org/acme/order/2369969697/379140500437"}
caddy-1  | {"level":"info","ts":1745949945.1671557,"msg":"got renewal info","names":["cloud.bunker496.de"],"window_start":1751053875,"window_end":1751209325,"selected_time":1751186786,"recheck_after":1745971545.1671438,"explanation_url":""}
caddy-1  | {"level":"info","ts":1745949945.507783,"msg":"got renewal info","names":["cloud.bunker496.de"],"window_start":1751053875,"window_end":1751209325,"selected_time":1751157916,"recheck_after":1745971545.5077777,"explanation_url":""}
caddy-1  | {"level":"info","ts":1745949945.5078173,"msg":"successfully downloaded available certificate chains","count":2,"first_url":"https://acme-v02.api.letsencrypt.org/acme/cert/05c9e5c87a71a52a1a2ddbfcbd8deab8736a"}
caddy-1  | {"level":"info","ts":1745949945.5161798,"logger":"tls.obtain","msg":"certificate obtained successfully","identifier":"cloud.bunker496.de","issuer":"acme-v02.api.letsencrypt.org-directory"}
caddy-1  | {"level":"info","ts":1745949945.5162508,"logger":"tls.obtain","msg":"releasing lock","identifier":"cloud.bunker496.de"}
caddy-1  | {"level":"error","ts":1745949978.625936,"logger":"http.log.error","msg":"strconv.Atoi: parsing \";\": invalid syntax","request":{"remote_ip":"188.192.XXX.XXX","remote_port":"51431","client_ip":"188.192.XXX.XXX","proto":"HTTP/3.0","method":"GET","host":"cloud.bunker496.de","uri":"/","headers":{"Sec-Fetch-Dest":["document"],"Cookie":["REDACTED"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Priority":["u=0, i"],"Sec-Gpc":["1"],"Sec-Fetch-User":["?1"],"Accept-Language":["en-GB,en;q=0.5"],"Sec-Ch-Ua":["\"Brave\";v=\"135\", \"Not-A.Brand\";v=\"8\", \"Chromium\";v=\"135\""],"Sec-Ch-Ua-Mobile":["?0"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"],"Sec-Fetch-Mode":["navigate"],"Sec-Ch-Ua-Platform":["\"Windows\""],"Upgrade-Insecure-Requests":["1"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"],"Sec-Fetch-Site":["none"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h3","server_name":"cloud.bunker496.de"}},"duration":0.00004305,"status":500,"err_id":"ggc9hds8m","err_trace":"caddyhttp.StaticResponse.ServeHTTP (staticresp.go:238)"}
caddy-1  | {"level":"error","ts":1745949979.729959,"logger":"http.log.error","msg":"strconv.Atoi: parsing \";\": invalid syntax","request":{"remote_ip":"188.192.XXX.XXX","remote_port":"51431","client_ip":"188.192.XXX.XXX","proto":"HTTP/3.0","method":"GET","host":"cloud.bunker496.de","uri":"/index.php/apps/files/preview-service-worker.js","headers":{"Cache-Control":["max-age=0"],"Accept":["*/*"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Sec-Fetch-Mode":["same-origin"],"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"],"Priority":["u=4, i"],"Referer":["https://cloud.bunker496.de/index.php/apps/files/preview-service-worker.js"],"Service-Worker":["script"],"Sec-Gpc":["1"],"Sec-Fetch-Site":["same-origin"],"Accept-Language":["en-GB,en;q=0.5"],"Sec-Fetch-Dest":["serviceworker"],"Cookie":["REDACTED"]},"tls":{"resumed":false,"version":772,"cipher_suite":4867,"proto":"h3","server_name":"cloud.bunker496.de"}},"duration":0.000025667,"status":500,"err_id":"qt947mmni","err_trace":"caddyhttp.StaticResponse.ServeHTTP (staticresp.go:238)"}
Gracefully stopping... (press Ctrl+C again to force)
[+] Stopping 1/1
 ✔ Container caddy-caddy-1  Stopped

3. Caddy version:

v2.10.0 h1:fonubSaQKF1YANl8TXqGcn4IbIRUDdfAkpcsfI/vX5U=

4. How I installed and ran Caddy:

a. System environment:

I’m running Caddy using Docker version 28.0.4, build b8034c0.
I’m running Docker on Ubuntu 24.04.2 LTS (Ubuntu server).
I’m running Ubuntu on Proxmox VE.

b. Command:

docker compose up

c. Service/unit/compose file:

services:
  caddy:
    image: caddy:latest
    cap_add:
      - NET_ADMIN
    ports:
      - "80:80/tcp"
      - "443:443/tcp"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile

NB: I know latest is bad practise - this is just for troubleshooting.

d. My complete Caddy config:

cloud.bunker496.de {
	respond "Hello, world!";
}

5. Links to relevant resources:

Simply, semicolon is not a thing in Caddyfile. Read the documentation:

1 Like

facepalms
Thank you very much for your answer! How does one tell from the logs that the error is related to the Caddyfile / config?

Eh, it technically snuck through the Caddyfile parser (it’s not invalid syntax per se, just highly unorthodox).

The line number in the error message points to: caddy/modules/caddyhttp/staticresp.go at aa3d20be3ee451af9465470a28937690104e9422 · caddyserver/caddy · GitHub

Since the token that’s enclosed by quotes ("Hello world!") ended, the next token to be parsed does not need a space before it. (We probably should require that, but meh, the Caddyfile syntax was never super rigidly defined.) So it thinks that ; should be a status code, or some value which equates to a status code.

1 Like