caddyserver/caddy · error

invalid to flag: %v

Error message

invalid to flag: %v

What it means

The 'caddy reverse-proxy' quick-start command failed to read the --to flag via fs.GetStringSlice. This only happens if the flag value cannot be interpreted as a string slice — in practice a flagparse/runtime issue, since string flags rarely fail — and the raw error is appended.

Source

Thrown at modules/caddyhttp/reverseproxy/command.go:103

}

func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
	caddy.TrapSignals()

	from := fs.String("from")
	changeHost := fs.Bool("change-host-header")
	insecure := fs.Bool("insecure")
	disableRedir := fs.Bool("disable-redirects")
	internalCerts := fs.Bool("internal-certs")
	accessLog := fs.Bool("access-log")
	debug := fs.Bool("debug")

	httpPort := strconv.Itoa(caddyhttp.DefaultHTTPPort)
	httpsPort := strconv.Itoa(caddyhttp.DefaultHTTPSPort)

	to, err := fs.GetStringSlice("to")
	if err != nil {
		return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid to flag: %v", err)
	}
	if len(to) == 0 {
		return caddy.ExitCodeFailedStartup, fmt.Errorf("--to is required")
	}

	// set up the downstream address; assume missing information from given parts
	fromAddr, err := httpcaddyfile.ParseAddress(from)
	if err != nil {
		return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid downstream address %s: %v", from, err)
	}
	if fromAddr.Path != "" {
		return caddy.ExitCodeFailedStartup, fmt.Errorf("paths are not allowed: %s", from)
	}
	if fromAddr.Scheme == "" {
		if fromAddr.Port == httpPort || fromAddr.Host == "" {
			fromAddr.Scheme = "http"
		} else {
			fromAddr.Scheme = "https"

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Re-run the command with a simple quoted --to value: caddy reverse-proxy --from localhost --to 'localhost:8080'.
  2. Check for stray shell expansion (unquoted braces, globbing) around the --to argument.
  3. If it persists, report the wrapped '%v' error — it indicates a flag-registration bug rather than bad input.

Example fix

# before
caddy reverse-proxy --from example.com --to backend:8080 backend:8081

# after
caddy reverse-proxy --from example.com --to backend:8080,backend:8081
Defensive patterns

Strategy: try-catch

Try / catch

to, err := fs.GetStringSlice("to")
if err != nil {
    // this path is nearly unreachable; treat as a tooling bug and surface the raw error
    return fmt.Errorf("reading --to flag: %w", err)
}

Prevention

When it happens

Trigger: Passing --to in a form the flag package rejects (e.g. repeated incompatible definitions via a custom flag set) when invoking 'caddy reverse-proxy --from ... --to ...'.

Common situations: Shell-level mangling of the command line, or a wrapper script redefining flags; most users will never see this because malformed --to values parse fine and fail later.

Related errors


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