caddyserver/caddy · error
parsing upstream '%s': %w
Error message
parsing upstream '%s': %w
What it means
While parsing the reverse_proxy directive's inline arguments (the upstream list on the directive line itself), appendUpstream failed for one address. The '%w' suffix is the underlying error, typically one of the parseUpstreamDialAddress failures (placeholders with scheme, bad port, path in URL, scheme/port conflict).
Source
Thrown at modules/caddyhttp/reverseproxy/caddyfile.go:218
Dial: pa.dialAddr(),
})
} else {
// expand a port range into multiple upstreams
for i := parsedAddr.StartPort; i <= parsedAddr.EndPort; i++ {
h.Upstreams = append(h.Upstreams, &Upstream{
Dial: caddy.JoinNetworkAddress("", parsedAddr.Host, fmt.Sprint(i)),
})
}
}
return nil
}
d.Next() // consume the directive name
for _, up := range d.RemainingArgs() {
err := appendUpstream(up)
if err != nil {
return fmt.Errorf("parsing upstream '%s': %w", up, err)
}
}
for d.NextBlock(0) {
// if the subdirective has an "@" prefix then we
// parse it as a response matcher for use with "handle_response"
if strings.HasPrefix(d.Val(), matcherPrefix) {
err := caddyhttp.ParseNamedResponseMatcher(d.NewFromNextSegment(), h.responseMatchers)
if err != nil {
return err
}
continue
}
switch d.Val() {
case "to":
args := d.RemainingArgs()
if len(args) == 0 {View on GitHub (pinned to 50e54ee279)
Solutions
- Locate the failing upstream named in the message ('parsing upstream 'X'') and fix it using the underlying error text.
- Apply the same fixes as for parseUpstreamDialAddress errors: no placeholders with schemes, no paths/queries, consistent scheme/port.
- Run 'caddy validate --config' after each upstream edit to isolate the bad entry quickly.
Example fix
# before reverse_proxy https://backend/api http://other:8080 # after reverse_proxy https://backend http://other:8080
Defensive patterns
Strategy: validation
Validate before calling
// validate inline upstreams with the same rules before adapting config
for _, up := range strings.Fields(upstreamLine) {
if strings.Contains(up, "://") {
if u, err := url.Parse(up); err != nil || u.Path != "" || u.RawQuery != "" || u.Fragment != "" {
return fmt.Errorf("inline upstream %q rejected", up)
}
}
} Prevention
- Lint each upstream in long lists individually to localize failures.
- Run 'caddy adapt' + 'caddy validate' in CI for every config change.
- Keep upstream addresses minimal: host or scheme://host[:port].
When it happens
Trigger: 'reverse_proxy upstream1 upstream2 ...' where one inline upstream is malformed, e.g. 'reverse_proxy https://{env.H} http://bad:!port'.
Common situations: Long upstream lists where one entry has a typo; converting from JSON to Caddyfile and carrying over full URLs with paths.
Related errors
- due to parsing difficulties, placeholders are not allowed wh
- parsing upstream URL: %v
- parsing upstream URL: parse "%v": port range invalid: %v
- for now, URLs for proxy upstreams only support scheme, host,
- invalid action type
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/16bb209b21fe0c52.
Report an issue: GitHub.