{"record":{"id":"a98c507f4d5eeb5b","repo":"jaegertracing/jaeger","slug":"invalid-version-format-v","errorCode":null,"errorMessage":"invalid version format: %v","messagePattern":"invalid version format: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/elasticsearch/esclient/version.go","lineNumber":39,"sourceCode":"\t\tVersion map[string]any `json:\"version\"`\n\t\tTagLine string         `json:\"tagline\"`\n\t}\n\tbody, err := c.request(ctx, elasticRequest{\n\t\tendpoint: \"\",\n\t\tmethod:   http.MethodGet,\n\t})\n\tif err != nil {\n\t\treturn es.PingResult{}, err\n\t}\n\tvar info clusterInfo\n\tif err := json.Unmarshal(body, &info); err != nil {\n\t\treturn es.PingResult{}, err\n\t}\n\n\tversionField := info.Version[\"number\"]\n\tversionNumber, isString := versionField.(string)\n\tif !isString {\n\t\treturn es.PingResult{}, fmt.Errorf(\"invalid version format: %v\", versionField)\n\t}\n\treturn es.PingResult{VersionNumber: versionNumber, TagLine: info.TagLine}, nil\n}\n","sourceCodeStart":21,"sourceCodeEnd":43,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/storage/elasticsearch/esclient/version.go#L21-L43","documentation":"ping calls the cluster info API and reads the Version[\"number\"] field from the response. That field is expected to be a JSON string (e.g. \"8.11.0\"); if it is present under the \"number\" key but is not a string, ping refuses to guess and returns \"invalid version format\" with the actual value. Callers (ResolveBackendVersion) use this to pick ES vs OpenSearch code paths, so a wrong type would silently break version dispatch.","triggerScenarios":"ResolveBackendVersion → ping against a server whose cluster info response has Version[\"number\"] as a non-string (nil, map, or number) — e.g. a proxy or OpenSearch-compatible service returning an unexpected body shape.","commonSituations":"Pointing Jaeger at a non-Elasticsearch endpoint (proxy, load balancer HTML error page is JSON-wrapped oddly, or a custom mock); upgrading Elasticsearch where the info payload changed; a misconfigured endpoint returning a cluster-info-like body from a different product.","solutions":["Confirm the endpoint is a real Elasticsearch/OpenSearch node: curl http://host:9200/ and check version.number is a plain string.","Check for proxies/LB that intercept / and return a transformed payload; point the client directly at the cluster.","Update the Elasticsearch/Opensearch client library if the server version changed the info payload serialization.","Inspect the value printed in the error to identify what the server actually returned (null suggests a missing/malformed response body)."],"exampleFix":"// before: hitting a proxy that returns {\"version\":{\"number\":8.1}}\nserver: \"http://proxy:8080\"\n// after: hit the ES node directly\nserver: \"http://es-node:9200\"","handlingStrategy":"type-guard","validationCode":"// verify the endpoint returns a plain ES cluster info first\nvar info struct {\n\tVersion struct{ Number string `json:\"number\"` } `json:\"version\"`\n}\nif err := json.NewDecoder(resp.Body).Decode(&info); err != nil || info.Version.Number == \"\" {\n\treturn fmt.Errorf(\"endpoint does not look like Elasticsearch\")\n}","typeGuard":"func versionNumberIsString(info map[string]interface{}) (string, bool) {\n\tv, ok := info[\"number\"]\n\ts, isStr := v.(string)\n\treturn s, ok && isStr\n}","tryCatchPattern":"pr, err := ResolveBackendVersion(ctx, client)\nif err != nil {\n\tif strings.Contains(err.Error(), \"invalid version format\") {\n\t\t// endpoint is not returning a standard cluster-info payload;\n\t\t// check what the server actually returned and fix the endpoint\n\t}\n\treturn err\n}","preventionTips":["Point Jaeger directly at a real Elasticsearch/OpenSearch node, not a proxy or LB that rewrites responses.","Smoke-test the endpoint with curl and confirm version.number is a plain string before configuring storage.","Pin and test against known server versions when upgrading the cluster.","Capture the offending value from the error message to diagnose transformed/blocked responses quickly."],"tags":["elasticsearch","version-parsing","type-mismatch"],"backgroundTag":"invalid-version-format","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}