{"record":{"id":"516299f4c0d33ac5","repo":"SigNoz/signoz","slug":"error-while-scanning-le-s","errorCode":null,"errorMessage":"error while scanning le: %s","messagePattern":"error while scanning le: (.+?)","errorType":"exception","errorClass":null,"httpStatus":500,"severity":"error","filePath":"pkg/query-service/app/clickhouseReader/reader.go","lineNumber":3316,"sourceCode":"\t\t\tWHERE metric_name = $1\n\t\t\t\tAND unix_milli >= $2\n\t\t\t\tAND type = 'Histogram'\n\t\t\t\tAND (JSONExtractString(labels, 'service_name') = $3 OR JSONExtractString(labels, 'service.name') = $4)\n\t\t\tGROUP BY le\n\t\t\tORDER BY le`, signozMetricDBName, signozTSTableNameV41Day)\n\t\t}\n\n\t\trows, err := r.db.Query(ctx, query, metricName, unixMilli, serviceName, serviceName)\n\t\tif err != nil {\n\t\t\tr.logger.Error(\"Error while querying histogram buckets\", errorsV2.Attr(err))\n\t\t\treturn nil, fmt.Errorf(\"error while querying histogram buckets: %s\", err.Error())\n\t\t}\n\t\tdefer rows.Close()\n\n\t\tfor rows.Next() {\n\t\t\tvar leStr string\n\t\t\tif err := rows.Scan(&leStr); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error while scanning le: %s\", err.Error())\n\t\t\t}\n\t\t\tle, err := strconv.ParseFloat(leStr, 64)\n\t\t\tif err != nil || math.IsInf(le, 0) {\n\t\t\t\tr.logger.Error(\"Invalid 'le' bucket value\", \"value\", leStr, errorsV2.Attr(err))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tleFloat64 = append(leFloat64, le)\n\t\t}\n\t}\n\n\treturn &v3.MetricMetadataResponse{\n\t\tDelta:       deltaExists,\n\t\tLe:          leFloat64,\n\t\tDescription: description,\n\t\tUnit:        unit,\n\t\tType:        metricType,\n\t\tIsMonotonic: isMonotonic,\n\t\tTemporality: temporality,","sourceCodeStart":3298,"sourceCodeEnd":3334,"githubUrl":"https://github.com/SigNoz/signoz/blob/5069bf80b08f1f00d7e014eccc09902f9871004f/pkg/query-service/app/clickhouseReader/reader.go#L3298-L3334","documentation":"Scan error while reading the 'le' (less-than-or-equal) bucket boundary column from histogram query results. It means the ClickHouse result row shape doesn't match the single-string scan target — e.g. le stored as a Float64/Array instead of String, or a NULL value.","triggerScenarios":"Histogram bucket query returns rows where le is NULL or a non-string type; schema drift in time_series_exp_histogram where le is materialized differently than the reader expects.","commonSituations":"SigNoz upgrade changed the le column type in the v4 histogram table; OTEL exporters emitting explicit-bucket histograms with missing/NULL le values; mixed old/new data after migration.","solutions":["Check the wrapped error for type-mismatch vs NULL indication","Inspect the actual column type: DESCRIBE signoz_metrics.time_series_v4_1_day","Re-run migrations so the histogram table schema matches the query-service version","Scan into sql.NullString or interface{} and convert defensively"],"exampleFix":"// before\nvar leStr string\nif err := rows.Scan(&leStr); err != nil { ... }\n\n// after\nvar leStr sql.NullString\nif err := rows.Scan(&leStr); err != nil { ... }\nif !leStr.Valid { continue }","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Treat unscannable le rows as skip-worthy, not fatal\nvar leStr sql.NullString\nif err := rows.Scan(&leStr); err != nil {\n    r.logger.Error(\"skipping bad le row\", errorsV2.Attr(err))\n    continue\n}","preventionTips":["Keep histogram table schema in sync with reader version","Use NullString scans for externally-controlled columns"],"tags":["signoz","clickhouse","histogram","scan-error"],"backgroundTag":"row-scan-type-mismatch","analyzedSha":"5069bf80b08f1f00d7e014eccc09902f9871004f","analyzedAt":"2026-08-28T06:22:12.824Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}