thanos-io/thanos · error

parsing downstream tripper TLS config YAML

Error message

parsing downstream tripper TLS config YAML

What it means

This error is returned when exthttp.NewTLSConfig fails to build a TLS configuration from the tls_config section of the downstream tripper config. It indicates the TLS fields (CA, cert, key, server name, etc.) are invalid — usually bad file paths or invalid content. Thanos wraps it to point at the downstream tripper TLS block.

Solutions

  1. Verify every path in tls_config (ca_file, cert_file, key_file) exists and is readable by the Thanos process.
  2. Ensure cert/key files contain valid PEM data.
  3. Read the wrapped underlying error for the exact failing field.
  4. If TLS is not needed for the downstream connection, remove the tls_config block.

Example fix

// before
tls_config:
  ca_file: /etc/secrets/ca.crtp
// after
tls_config:
  ca_file: /etc/secrets/ca.crt
Defensive patterns

Strategy: validation

Validate before calling

for _, p := range []string{tlsCfg.CAFile, tlsCfg.CertFile, tlsCfg.KeyFile} {
  if p != "" {
    if _, err := os.Stat(p); err != nil {
      return fmt.Errorf("TLS file %s missing: %w", p, err)
    }
  }
}

Try / catch

if _, err := exthttp.NewTLSConfig(tlsConf); err != nil {
  log.Fatalf("downstream TLS config invalid: %v", err)
}

Prevention

When it happens

Trigger: tls_config present in the downstream tripper YAML with a ca_file/cert_file/key_file that does not exist or is unreadable, invalid PEM content, or invalid insecure_skip_verify/server_name combinations rejected by exthttp.NewTLSConfig.

Common situations: Mount path changes in Kubernetes breaking cert paths, secrets not mounted, certs expired/replaced, or typo in file names inside tls_config.

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


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/a548455dbab7dbc8. Report an issue: GitHub.

Appendix: source

Thrown at cmd/thanos/query_frontend.go:212

			DualStack: true,
		}).DialContext,
		ForceAttemptHTTP2:     true,
		MaxIdleConns:          100,
		IdleConnTimeout:       90 * time.Second,
		TLSHandshakeTimeout:   10 * time.Second,
		ExpectContinueTimeout: 1 * time.Second,
	}

	if len(downstreamTripperConfContentYaml) > 0 {
		tripperConfig := &queryfrontend.DownstreamTripperConfig{}
		if err := yaml.UnmarshalStrict(downstreamTripperConfContentYaml, tripperConfig); err != nil {
			return nil, errors.Wrap(err, "parsing downstream tripper config YAML file")
		}

		if tripperConfig.TLSConfig != nil {
			tlsConfig, err := exthttp.NewTLSConfig(tripperConfig.TLSConfig)
			if err != nil {
				return nil, errors.Wrap(err, "parsing downstream tripper TLS config YAML")
			}
			downstreamTripper.TLSClientConfig = tlsConfig
		}
		if tripperConfig.IdleConnTimeout > 0 {
			downstreamTripper.IdleConnTimeout = time.Duration(tripperConfig.IdleConnTimeout)
		}
		if tripperConfig.ResponseHeaderTimeout > 0 {
			downstreamTripper.ResponseHeaderTimeout = time.Duration(tripperConfig.ResponseHeaderTimeout)
		}
		if tripperConfig.TLSHandshakeTimeout > 0 {
			downstreamTripper.TLSHandshakeTimeout = time.Duration(tripperConfig.TLSHandshakeTimeout)
		}
		if tripperConfig.ExpectContinueTimeout > 0 {
			downstreamTripper.ExpectContinueTimeout = time.Duration(tripperConfig.ExpectContinueTimeout)
		}
		if tripperConfig.MaxIdleConns != nil {
			downstreamTripper.MaxIdleConns = *tripperConfig.MaxIdleConns
		}

View on GitHub (pinned to 35b8b99117)