{"record":{"id":"940edc08ddd021a2","repo":"thanos-io/thanos","slug":"creating-request-to-downstream-url","errorCode":null,"errorMessage":"creating request to downstream URL","messagePattern":"creating request to downstream URL","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/thanos/query_frontend.go","lineNumber":416,"sourceCode":"\t\t\tsrv.Shutdown(err)\n\t\t})\n\t}\n\n\t// Periodically check downstream URL to ensure it is reachable.\n\t{\n\t\tctx, cancel := context.WithCancel(context.Background())\n\n\t\tg.Add(func() error {\n\t\t\tvar firstRun = true\n\n\t\t\tdoCheckDownstream := func() (rerr error) {\n\t\t\t\ttimeoutCtx, cancel := context.WithTimeout(ctx, 10*time.Second)\n\t\t\t\tdefer cancel()\n\n\t\t\t\treadinessUrl := cfg.DownstreamURL + \"/-/ready\"\n\t\t\t\treq, err := http.NewRequestWithContext(timeoutCtx, http.MethodGet, readinessUrl, nil)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn errors.Wrap(err, \"creating request to downstream URL\")\n\t\t\t\t}\n\n\t\t\t\tresp, err := downstreamRT.RoundTrip(req)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn errors.Wrapf(err, \"roundtripping to downstream URL %s\", readinessUrl)\n\t\t\t\t}\n\t\t\t\tdefer runutil.CloseWithErrCapture(&rerr, resp.Body, \"downstream health check response body\")\n\n\t\t\t\tif resp.StatusCode/100 == 4 || resp.StatusCode/100 == 5 {\n\t\t\t\t\treturn errors.Errorf(\"downstream URL %s returned an error: %d\", readinessUrl, resp.StatusCode)\n\t\t\t\t}\n\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tfor {\n\t\t\t\tif !firstRun {\n\t\t\t\t\tselect {\n\t\t\t\t\tcase <-ctx.Done():","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/cmd/thanos/query_frontend.go#L398-L434","documentation":"Inside the readiness actor, Thanos builds a GET request to <downstream-url>/-/ready using http.NewRequestWithContext and wraps construction failures with this message. http.NewRequest only errors on malformed URLs or invalid method/context, so this indicates the downstream URL could not be turned into a valid request.","triggerScenarios":"cfg.DownstreamURL malformed (bad scheme, invalid characters, empty) such that appending '/-/ready' yields a URL http.NewRequestWithContext rejects; invalid context.","commonSituations":"Downstream URL configured without scheme, containing spaces or invalid characters, or misquoted in a shell so the flag receives garbage.","solutions":["Fix --query-frontend.downstream-url to a well-formed absolute URL with scheme (http:// or https://).","Manually curl <downstream-url>/-/ready to confirm the URL is usable.","Check shell quoting/interpolation that may inject spaces or variables into the flag value.","Read the wrapped parse error to see the rejected URL exactly."],"exampleFix":"// before\n--query-frontend.downstream-url=http://query-frontend :9090\n// after\n--query-frontend.downstream-url=http://query-frontend:9090","handlingStrategy":"try-catch","validationCode":"u, err := url.Parse(downstreamURL + \"/-/ready\")\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n  return fmt.Errorf(\"ready probe url invalid: %q\", downstreamURL)\n}","typeGuard":null,"tryCatchPattern":"req, err := http.NewRequestWithContext(ctx, http.MethodGet, readyURL, nil)\nif err != nil {\n  return fmt.Errorf(\"creating request to downstream URL: %w\", err)\n}","preventionTips":["Verify downstream-url with curl before startup","Quote shell variables feeding the flag","Build the readiness URL via url.JoinPath to avoid malformed joins"],"tags":["url","readiness","http"],"backgroundTag":"invalid-url-format","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}