thanos-io/thanos · error
Improper http client config
Error message
Improper http client config
What it means
Once the YAML parses into an HTTPClientConfig, the sidecar constructs a usable client with clientconfig.NewHTTPClient(*httpClientConfig, "thanos-sidecar"). This step validates semantic combinations (e.g. both bearer_token and bearer_token_file set, missing cert/key pairing) that YAML parsing alone accepts. Failures abort startup with "Improper http client config".
Solutions
- Read the wrapped error from NewHTTPClient — it names the exact invalid combination (e.g. 'authorization config: at most one of basic_auth, oauth2, bearer_token & bearer_token_file must be configured').
- Keep exactly one credential mechanism: either bearer_token OR bearer_token_file, not both.
- Ensure TLS pairs are complete: cert_file always together with key_file, and CA/key files exist and are readable by the sidecar process.
- Remove mutually exclusive fields until the config passes, then reintroduce one at a time.
Example fix
// before
{"bearer_token": "abc", "bearer_token_file": "/var/run/token"}
// after
{"bearer_token_file": "/var/run/token"} Defensive patterns
Strategy: validation
Validate before calling
func semanticallyValid(cfg clientconfig.HTTPClientConfig) error {
if cfg.BearerToken != "" && cfg.BearerTokenFile != "" {
return errors.New("at most one of bearer_token / bearer_token_file")
}
if (cfg.TLSConfig.CertFile != "") != (cfg.TLSConfig.KeyFile != "") {
return errors.New("cert_file and key_file must be set together")
}
return nil
} Type guard
null
Try / catch
httpClient, err := clientconfig.NewHTTPClient(*httpClientConfig, "thanos-sidecar")
if err != nil {
return fmt.Errorf("Improper http client config: %w", err)
} Prevention
- Never set both inline credentials and credential files — pick one mechanism
- Always pair cert_file with key_file and verify the files are readable by the process
- Construct the client in a startup smoke test so semantic config errors surface before production
When it happens
Trigger: Calling NewHTTPClient with a config that is structurally valid YAML but semantically invalid — e.g. specifying both bearer_token and bearer_token_file, cert_file without key_file, or an unreadable CA file path — at cmd/thanos/sidecar.go:83.
Common situations: Setting both inline credentials and credential files; TLS cert provided without its key; secret files mounted at the wrong path so the client can't load them; authorization/basic_auth configured alongside mutually exclusive fields.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- getting http client config
- parsing http config YAML
- failed to create HTTP query client
- failed to parse template
- failed to execute template
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/448111fe67e919e5.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/thanos/sidecar.go:84
grpcLogOpts, logFilterMethods, err := logging.ParsegRPCOptions(conf.reqLogConfig)
if err != nil {
return errors.Wrap(err, "error while parsing config for request logging")
}
httpConfContentYaml, err := conf.prometheus.httpClient.Content()
if err != nil {
return errors.Wrap(err, "getting http client config")
}
httpClientConfig, err := clientconfig.NewHTTPClientConfigFromYAML(httpConfContentYaml)
if err != nil {
return errors.Wrap(err, "parsing http config YAML")
}
httpClient, err := clientconfig.NewHTTPClient(*httpClientConfig, "thanos-sidecar")
if err != nil {
return errors.Wrap(err, "Improper http client config")
}
opts := reloader.Options{
HTTPClient: *httpClient,
CfgFile: conf.reloader.confFile,
CfgOutputFile: conf.reloader.envVarConfFile,
WatchedDirs: conf.reloader.ruleDirectories,
WatchInterval: conf.reloader.watchInterval,
RetryInterval: conf.reloader.retryInterval,
}
switch conf.reloader.method {
case HTTPReloadMethod:
opts.ReloadURL = reloader.ReloadURLFromBase(conf.prometheus.url)
case SignalReloadMethod:
opts.ProcessName = conf.reloader.processName
opts.RuntimeInfoURL = reloader.RuntimeInfoURLFromBase(conf.prometheus.url)
default:View on GitHub (pinned to 35b8b99117)