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

  1. Read the wrapped error text — it names the exact option and reason; fix that token in the global options block
  2. Verify the option exists in your Caddy version (check `caddy adapt` against current docs)
  3. If adapting programmatically, validate option values before calling Setup
  4. 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

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


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/396959491b1dd01f. Report an issue: GitHub.