{"record":{"id":"8fd64aac22b2966d","repo":"jaegertracing/jaeger","slug":"trace-id-from-db-is-too-long-d-chars","errorCode":null,"errorMessage":"trace ID from DB is too long: %d chars","messagePattern":"trace ID from DB is too long: (.+?) chars","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/v2/elasticsearch/tracestore/ids.go","lineNumber":20,"sourceCode":"// SPDX-License-Identifier: Apache-2.0\n\npackage tracestore\n\nimport (\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"go.opentelemetry.io/collector/pdata/pcommon\"\n\n\t\"github.com/jaegertracing/jaeger/internal/storage/v2/elasticsearch/tracestore/core/dbmodel\"\n)\n\nfunc convertTraceIDFromDB(dbTraceId dbmodel.TraceID) (pcommon.TraceID, error) {\n\tvar traceId [16]byte\n\ttraceIdHex := string(dbTraceId)\n\tif len(traceIdHex) > 32 {\n\t\treturn pcommon.TraceID{}, fmt.Errorf(\"trace ID from DB is too long: %d chars\", len(traceIdHex))\n\t}\n\t// Left-pad with zeros to 32 hex chars to handle shorter (e.g. 64-bit) trace IDs.\n\tif len(traceIdHex) < 32 {\n\t\ttraceIdHex = strings.Repeat(\"0\", 32-len(traceIdHex)) + traceIdHex\n\t}\n\ttraceBytes, err := hex.DecodeString(traceIdHex)\n\tif err != nil {\n\t\treturn pcommon.TraceID{}, err\n\t}\n\tcopy(traceId[:], traceBytes)\n\treturn traceId, nil\n}\n\nfunc fromDbSpanId(dbSpanId dbmodel.SpanID) (pcommon.SpanID, error) {\n\tvar spanId [8]byte\n\tspanIdHex := string(dbSpanId)\n\tif len(spanIdHex) > 16 {\n\t\treturn pcommon.SpanID{}, fmt.Errorf(\"span ID from DB is too long: %d chars\", len(spanIdHex))","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/storage/v2/elasticsearch/tracestore/ids.go#L2-L38","documentation":"convertTraceIDFromDB converts a stored DB trace ID (hex string) into a pcommon.TraceID. It rejects any trace ID longer than 32 hex characters (128 bits), since that cannot fit into the 16-byte OTLP TraceID. This indicates corrupt or non-conformant data in Elasticsearch rather than a caller bug.","triggerScenarios":"Reading spans or trace summaries from Elasticsearch whose trace_id field contains more than 32 hex characters, via GetTraces, FindTraceSummaries, or related read paths that call dbSpanToSpan/dbSpanRefsToSpanEvents.","commonSituations":"An index written by a different/older jaeger schema or manually seeded documents with malformed trace_id; a custom ingester storing non-standard-width trace IDs; data migration from another backend leaving oversized IDs.","solutions":["Inspect the offending document's trace_id field in Elasticsearch and correct or delete the malformed record","Ensure all writes go through jaeger's ES span writer so trace IDs are canonical hex","Check for scripts/migrations that transformed trace IDs (e.g. re-encoding base64 to hex twice)","Pin reader/writer versions so both use the same dbmodel schema"],"exampleFix":"// before (corrupt document in ES)\n{\"trace_id\": \"a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0\"}\n// after\n{\"trace_id\": \"a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6\"}","handlingStrategy":"validation","validationCode":"if len(span.GetTraceId()) > 32 {\n    return fmt.Errorf(\"trace ID exceeds 32 hex chars: %d\", len(span.GetTraceId()))\n}","typeGuard":"func isValidTraceIDHex(s string) bool {\n    return len(s) <= 32 && len(s) > 0\n}","tryCatchPattern":null,"preventionTips":["Only write spans through jaeger's official ES writer","Validate trace_id width in any custom ingestion pipeline","Run a one-off reindex validation when migrating backends"],"tags":["storage","elasticsearch","data-corruption"],"backgroundTag":"invalid-trace-id","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}