caddyserver/caddy · error
applying global server options: %v
Error message
applying global server options: %v
What it means
Raised when applyServerOptions fails while applying Caddyfile global options (e.g. `servers`, `grace_period`, `shutdown_delay`, `timeouts`, `max_header_size`, `trusted_proxies`, `metrics`) to the generated set of HTTP servers. The original error from the option parser is wrapped with 'applying global server options'.
Source
Thrown at caddyconfig/httpcaddyfile/httptype.go:1113
(len(srv.TLSConnPolicies) > 0 || !autoHTTPSWillAddConnPolicy || defaultSNI != "" || fallbackSNI != "") {
srv.TLSConnPolicies = append(srv.TLSConnPolicies, &caddytls.ConnectionPolicy{
DefaultSNI: defaultSNI,
FallbackSNI: fallbackSNI,
})
}
// tidy things up a bit
srv.TLSConnPolicies, err = consolidateConnPolicies(srv.TLSConnPolicies)
if err != nil {
return nil, fmt.Errorf("consolidating TLS connection policies for server %d: %v", i, err)
}
srv.Routes = consolidateRoutes(srv.Routes)
servers[fmt.Sprintf("srv%d", i)] = srv
}
if err := applyServerOptions(servers, options, warnings); err != nil {
return nil, fmt.Errorf("applying global server options: %v", err)
}
return servers, nil
}
// sniNames returns the server names a connection policy's sni matcher matches.
// The bool is false when the policy has no sni matcher, or when it does not
// decode - the latter is unexpected enough to warn about rather than silently
// skip, since callers use it to decide whether a hostname needs shielding.
func sniNames(cp *caddytls.ConnectionPolicy, what string, warnings *[]caddyconfig.Warning) ([]string, bool) {
raw, ok := cp.MatchersRaw["sni"]
if !ok {
return nil, false
}
var sni caddytls.MatchServerName
if err := json.Unmarshal(raw, &sni); err != nil {
*warnings = append(*warnings, caddyconfig.Warning{
Message: fmt.Sprintf("decoding sni matcher %swhile checking wildcard coverage: %v", what, err),View on GitHub (pinned to 50e54ee279)
Solutions
- Read the wrapped error text — it names the exact option and reason; fix that token in the global options block
- Verify the option exists in your Caddy version (check `caddy adapt` against current docs)
- If adapting programmatically, validate option values before calling Setup
- Remove the offending subdirective and re-adapt to isolate it
Example fix
# before
{
servers {
read_timeout notanumber
}
}
# after
{
servers {
read_timeout 30s
}
} Defensive patterns
Strategy: validation
Validate before calling
// Programmatically: validate global option values before calling ServerType.Setup
if v, ok := options["servers"]; ok {
if _, ok := v.(string); !ok { return fmt.Errorf("servers option malformed") }
} Try / catch
out, warn, err := caddyfile.Adapt(cfg, map[string]any{"filename":"Caddyfile"})
if err != nil {
return fmt.Errorf("adapt failed (check global options block): %w", err)
} Prevention
- Keep global options minimal and version-checked
- After upgrading Caddy, re-run caddy adapt before reload
- Use `caddy validate --config Caddyfile` in deployment scripts
When it happens
Trigger: Calling the Caddyfile adapter with a global `servers` block containing an invalid subdirective or bad value (e.g. `servers { read_timeout notanumber }`), an unknown protocol name in `protocols h3`, invalid `trusted_proxies` CIDR, or a listener address string that cannot be parsed — all of which make applyServerOptions return an error after the servers map was built.
Common situations: Upgrading Caddy versions where global server option names changed (e.g. older `max_header_size` moved under `servers`), typos in the global options block, or programmatically invoking caddyfile.ServerType.Setup with an options map missing required values.
Related errors
- consolidating TLS connection policies for server %d: %v
- unknown object ID '%s'
- decoding request body: %w, at offset %d
- decoding request body: %w
- no traversable path
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/396959491b1dd01f.
Report an issue: GitHub.