{"record":{"id":"715a50430bc47c6d","repo":"caddyserver/caddy","slug":"invalid-upstream-address-s-v","errorCode":null,"errorMessage":"invalid upstream address %s: %v","messagePattern":"invalid upstream address (.+?): (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddyhttp/reverseproxy/command.go","lineNumber":140,"sourceCode":"\t\t}\n\t}\n\tif fromAddr.Port == \"\" {\n\t\tswitch fromAddr.Scheme {\n\t\tcase \"http\":\n\t\t\tfromAddr.Port = httpPort\n\t\tcase \"https\":\n\t\t\tfromAddr.Port = httpsPort\n\t\t}\n\t}\n\n\t// set up the upstream address; assume missing information from given parts\n\t// mixing schemes isn't supported, so use first defined (if available)\n\ttoAddresses := make([]string, len(to))\n\tvar toScheme string\n\tfor i, toLoc := range to {\n\t\taddr, err := parseUpstreamDialAddress(toLoc)\n\t\tif err != nil {\n\t\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"invalid upstream address %s: %v\", toLoc, err)\n\t\t}\n\t\tif addr.scheme != \"\" && toScheme == \"\" {\n\t\t\ttoScheme = addr.scheme\n\t\t}\n\t\ttoAddresses[i] = addr.dialAddr()\n\t}\n\n\t// proceed to build the handler and server\n\tht := HTTPTransport{}\n\tif toScheme == \"https\" {\n\t\tht.TLS = new(TLSConfig)\n\t\tif insecure {\n\t\t\tht.TLS.InsecureSkipVerify = true\n\t\t}\n\t}\n\n\tupstreamPool := UpstreamPool{}\n\tfor _, toAddr := range toAddresses {","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/reverseproxy/command.go#L122-L158","documentation":"One of the --to upstream values failed parseUpstreamDialAddress while the command was normalizing upstream addresses. This is the CLI equivalent of the Caddyfile upstream parse errors: scheme+placeholder conflicts, bad ports, paths in URLs, or scheme/port conflicts, surfaced under 'invalid upstream address %s'.","triggerScenarios":"'caddy reverse-proxy --from x --to https://{env.H}', '--to http://host/path', '--to http://host:443', or any dial-address syntax violation from the parseUpstreamDialAddress rules.","commonSituations":"First-time users pasting full backend URLs with paths; env-var-driven deployments attempting placeholders in the scheme-bearing address.","solutions":["Fix the named upstream per the underlying error: host[:port] or scheme://host[:port] only.","Move path rewriting into a Caddyfile (rewrite + reverse_proxy) instead of the quick command.","Re-run with a minimal known-good --to like 'localhost:8080' to confirm the rest of the command works."],"exampleFix":"# before\ncaddy reverse-proxy --from example.com --to http://backend:9000/api\n\n# after\ncaddy reverse-proxy --from example.com --to http://backend:9000","handlingStrategy":"validation","validationCode":"for _, t := range toValues {\n    if strings.Contains(t, \"://\") {\n        if strings.Contains(t, \"{\") {\n            return fmt.Errorf(\"--to %q: placeholders not allowed with a scheme\", t)\n        }\n        if u, err := url.Parse(t); err != nil || u.Path != \"\" || u.RawQuery != \"\" || u.Fragment != \"\" {\n            return fmt.Errorf(\"--to %q must be scheme://host[:port] only\", t)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use bare host:port for --to and enable TLS via flags/config, not URL decoration.","Do path rewriting in a Caddyfile, not the quick command.","Smoke-test with --to localhost:8080 before complex backends."],"tags":["cli","reverse-proxy","upstream","startup"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}