1. The problem I’m having:
I’m experiencing an issue with my Caddyfile configuration where the header
directive is being parsed as a site address instead of a known directive. This error persists despite ensuring all directives are within site blocks. The specific error message is:
Error: adapting config using caddyfile: /etc/caddy/Caddyfile:35: parsed 'header' as a site address, but it is a known directive; directives must appear in a site block
2. Error messages and/or full log output:
The full error message is shown above. I’ve checked the logs using journalctl -u caddy --no-pager | less +G
, but there are no additional details beyond the error message.
3. Caddy version:
I’m using Caddy version 2.9.1, installed via the caddy-custom AUR package.
4. How I installed and ran Caddy:
a. System environment:
- OS: Arch Linux ARM
- Architecture: ARM
- Relevant versions: Caddy 2.9.1, Authelia v4.38.19
- Systemd: Yes
b. Command:
I run Caddy using a systemd service:
sudo systemctl start caddy
c. Service/unit/compose file:
My Caddy service file is as follows:
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
d. My complete Caddy config:
{
email laniecarmelo@gmail.com
debug
acme_dns cloudflare JpbcXkgbLQA3hSkl6WOWd_sm9tQvseuDGsf0mWsQ
http_port 80
https_port 443
admin :2019 {
origins 127.0.0.1:2019 0.0.0.0:2019 stormux:2019 caddy.laniecarmelo.tech
}
}
(logconfig) {
log {
output stdout
format json
}
}
(proxy_config) {
header_up Host {http.request.host}
header_up X-Real-IP {http.request.remote}
}
(authelia_middleware) {
forward_auth 127.0.0.1:9091 {
uri /api/verify
copy_headers Remote-User Remote-Email Remote-Groups Authorization
header_up X-Forwarded-Method {method}
header_up X-Forwarded-Proto {scheme}
header_up X-Original-URL {orig_uri}
}
}
(security_headers) {
header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
header X-XSS-Protection "1; mode=block"
header X-Content-Type-Options "nosniff"
header Referrer-Policy "strict-origin-when-cross-origin"
header Permissions-Policy "geolocation=(), midi=(), sync-xhr=(), microphone=(), camera=(), magnetometer=(), gyroscope=(), fullscreen=(self), payment=()"
}
# Authentication Service
auth.laniecarmelo.tech {
reverse_proxy 127.0.0.1:9091 {
import proxy_config
}
import logconfig
import security_headers
}
# Grouped Services with Simple Reverse Proxy
home.laniecarmelo.tech {
import authelia_middleware
reverse_proxy 127.0.0.1:3000 {
import proxy_config
}
import logconfig
import security_headers
}
adguard.laniecarmelo.tech {
@api {
path /control* /api*
}
route @api {
reverse_proxy 127.0.0.1:3001 {
import proxy_config
}
}
route {
import authelia_middleware
reverse_proxy 127.0.0.1:3001 {
import proxy_config
}
}
import logconfig
import security_headers
}
portainer.laniecarmelo.tech {
@api {
path /api/* /auth/*
}
route @api {
reverse_proxy 127.0.0.1:3002 {
import proxy_config
}
}
route {
import authelia_middleware
reverse_proxy 127.0.0.1:3002 {
import proxy_config
}
}
import logconfig
import security_headers
}
dozzle.laniecarmelo.tech {
import authelia_middleware
reverse_proxy 127.0.0.1:8080 {
import proxy_config
}
import logconfig
import security_headers
}
uptime.laniecarmelo.tech {
@api {
path /api/* /status/* /status-page/*
}
route @api {
reverse_proxy 127.0.0.1:3006 {
import proxy_config
}
redir /api/status-page/* /api/status/{path_1}
}
route {
import authelia_middleware
reverse_proxy 127.0.0.1:3006 {
import proxy_config
}
}
import logconfig
import security_headers
}
recipes.laniecarmelo.tech {
@api {
path /api/*
}
route @api {
reverse_proxy 127.0.0.1:8081 {
import proxy_config
}
}
route {
import authelia_middleware
reverse_proxy 127.0.0.1:8081 {
import proxy_config
}
}
handle /media/* {
root * /opt/docker/tandoor/media_files
file_server {
hide .env
hide docker-compose.yml
}
}
import logconfig
import security_headers
}
bookmarks.laniecarmelo.tech {
redir https://{host}{uri}
reverse_proxy 127.0.0.1:3009 {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-Proto {scheme}
header_response Location {replace "http://bookmarks.laniecarmelo.tech" "https://bookmarks.laniecarmelo.tech"}
}
import security_headers
import logconfig
}
git.laniecarmelo.tech {
@api {
path /api/* /api/v1/* /login/oauth/*
}
route @api {
reverse_proxy 127.0.0.1:3008 {
header_up Remote-User {http.auth.user.id}
header_up Remote-Email {http.auth.user.email}
import proxy_config
}
}
route {
import authelia_middleware
reverse_proxy 127.0.0.1:3008 {
header_up Remote-User {http.auth.user.id}
header_up Remote-Email {http.auth.user.email}
import proxy_config
}
}
import logconfig
import security_headers
}
irc.laniecarmelo.tech {
import authelia_middleware
reverse_proxy 127.0.0.1:3011 {
import proxy_config
}
import logconfig
import security_headers
}
code.laniecarmelo.tech {
import authelia_middleware
reverse_proxy 127.0.0.1:3012 {
import proxy_config
}
import logconfig
import security_headers
}
wiki.laniecarmelo.tech {
import authelia_middleware
reverse_proxy 127.0.0.1:5000 {
import proxy_config
}
import logconfig
import security_headers
}
glances.laniecarmelo.tech {
@api {
path /api/*
}
route @api {
reverse_proxy 127.0.0.1:61208 {
import proxy_config
}
}
route {
import authelia_middleware
reverse_proxy 127.0.0.1:61208 {
import proxy_config
}
encode gzip
}
encode gzip
handle_errors {
respond "Accessibility-first error: {err.status_code}"
}
import logconfig
import security_headers
}
beszel.laniecarmelo.tech {
@api {
path /api/* /metrics*
}
route @api {
reverse_proxy 127.0.0.1:8090 {
import proxy_config
}
}
route {
import authelia_middleware
reverse_proxy 127.0.0.1:8090 {
import proxy_config
}
}
import logconfig
import security_headers
}
caddy.laniecarmelo.tech {
@api {
path /reverse_proxy/*
}
route @api {
reverse_proxy 127.0.0.1:2019 {
import proxy_config
}
}
route {
import authelia_middleware
reverse_proxy 127.0.0.1:2019 {
import proxy_config
}
}
import logconfig
import security_headers
}
rss.laniecarmelo.tech {
@api {
path /api/* /reader/api/* /v1/*
}
route @api {
reverse_proxy 127.0.0.1:3010 {
import proxy_config
}
}
route {
import authelia_middleware
reverse_proxy 127.0.0.1:3010 {
import proxy_config
}
}
import logconfig
import security_headers
}
# Fallback for undefined subdomains
*.laniecarmelo.tech {
encode gzip
header Content-Security-Policy "default-src 'self';"
respond "Not Found" 404
}
5. Links to relevant resources:
Troubleshooting Steps Taken:
- Checked Directive Placement: Ensured all
header
directives are within site blocks. - Reviewed Snippets: Verified that snippets are correctly defined and used within site blocks.
- Validated Indentation: Confirmed proper indentation and no stray characters.
- Simplified Configuration: Removed unnecessary directives to isolate the issue.
If you have any suggestions or insights, please let me know!