thanos-io/thanos · error
otlp: invalid client type. Only 'http' and 'grpc' are…
Error message
otlp: invalid client type. Only 'http' and 'grpc' are accepted.
What it means
In pkg/tracing/otlp NewTracerProvider, the switch over the configured OTLP client type only handles 'http' and 'grpc'; any other value reaches the default branch and returns this sentinel error. OTLP exporter construction never happens, so no spans can be exported.
Solutions
- Set the OTLP client type to exactly 'http' or 'grpc' (lowercase, no slashes)
- Use 'grpc' for port 4317 and 'http' for port 4318 to match your collector
- Fix typos and avoid casing variants
- Consult the wrapped error/logs to confirm which value was parsed
Example fix
// before config: client_type: HTTP/protobuf endpoint: otel:4318 // after config: client_type: http endpoint: otel:4318
Defensive patterns
Strategy: validation
Validate before calling
// Before invoking the OTLP tracing path
if ct, ok := cfg["client_type"]; !ok {
return fmt.Errorf("otlp config missing client_type")
} else if ct != "http" && ct != "grpc" {
return fmt.Errorf("otlp client_type %q invalid: only 'http' and 'grpc' accepted", ct)
} Type guard
func validOTLPClientType(v interface{}) bool {
s, ok := v.(string)
return ok && (s == "http" || s == "grpc")
} Try / catch
tracer, closer, err := tracing.NewTracer(ctx, logger, reg, cfgYaml)
if err != nil && strings.Contains(err.Error(), "invalid client type") {
logger.Error(err, "set otlp client_type to 'http' or 'grpc'")
return err
} Prevention
- Use lowercase 'http' or 'grpc' with no slashes or casing variants
- Pick the type matching your collector port (4317=grpc, 4318=http)
- Do not copy OpenTelemetry SDK exporter names (http/protobuf) into this field
When it happens
Trigger: OTLP tracing config with client_type set to something other than 'http' or 'grpc' (e.g. 'http/protobuf', 'HTTP', 'grcp', or empty).
Common situations: Copying OpenTelemetry SDK config conventions (http/protobuf) into Thanos config, casing mistakes, or typos like 'grcp'.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- tracing failed
- error getting tenant from HTTP
- internal server error
- Error decoding remote write request
- error converting OTLP metrics to Prometheus format
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/05c91972e8910ba4.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/tracing/otlp/otlp.go:65
case TracingClientHTTP:
options := traceHTTPOptions(config)
client := otlptracehttp.NewClient(options...)
exporter, err = otlptrace.New(ctx, client)
if err != nil {
return nil, err
}
case TracingClientGRPC:
options := traceGRPCOptions(config)
client := otlptracegrpc.NewClient(options...)
exporter, err = otlptrace.New(ctx, client)
if err != nil {
return nil, err
}
default:
return nil, errors.New("otlp: invalid client type. Only 'http' and 'grpc' are accepted. ")
}
processor := tracesdk.NewBatchSpanProcessor(exporter)
sampler, err := getSampler(config)
if err != nil {
logger.Log(err)
}
tp := newTraceProvider(ctx, processor, logger, config.ServiceName, config.ResourceAttributes, sampler)
return tp, nil
}
func newTraceProvider(
ctx context.Context,
processor tracesdk.SpanProcessor,
logger log.Logger,
serviceName string,
attrs map[string]string,View on GitHub (pinned to 35b8b99117)