{"record":{"id":"92f3a62a57aadc44","repo":"apache/druid","slug":"unknown-version-s-of-metricholder","errorCode":null,"errorMessage":"Unknown version[%s] of MetricHolder","messagePattern":"Unknown version\\[(.+?)\\] of MetricHolder","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/MetricHolder.java","lineNumber":48,"sourceCode":"\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\n\n/**\n */\npublic class MetricHolder\n{\n  private static final byte[] VERSION = new byte[]{0x0};\n  private static final SerializerUtils SERIALIZER_UTILS = new SerializerUtils();\n\n  /**\n   * Read a metric column from a legacy (v8) segment.\n   */\n  public static MetricHolder fromByteBuffer(ByteBuffer buf)\n  {\n    final byte ver = buf.get();\n    if (VERSION[0] != ver) {\n      throw new ISE(\"Unknown version[%s] of MetricHolder\", ver);\n    }\n\n    final String metricName = SERIALIZER_UTILS.readString(buf);\n    final String typeName = SERIALIZER_UTILS.readString(buf);\n    MetricHolder holder = new MetricHolder(metricName, typeName);\n\n    switch (holder.type) {\n      case FLOAT:\n        holder.floatType = CompressedColumnarFloatsSupplier.fromByteBuffer(\n            buf,\n            ByteOrder.nativeOrder(),\n            null // OK since this method is only used for legacy segments, which always use version 1 indexed\n        );\n        break;\n      case COMPLEX:\n        final ComplexMetricSerde serdeForType = ComplexMetrics.getSerdeForType(holder.getTypeName());\n\n        if (serdeForType == null) {","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/MetricHolder.java#L30-L66","documentation":"MetricHolder.fromByteBuffer reads a legacy (v8) segment metric column and throws ISE if the version byte is not the expected VERSION[0]. This protects against reading metric columns in an on-disk format the loader cannot parse.","triggerScenarios":"Reading a metric column whose stored version byte differs from the expected one — corrupted segment files, hand-modified segments, or segments written by incompatible Druid versions.","commonSituations":"Mounting segments copied from a different Druid version or disk-format era; truncated/corrupted segment files on deep storage or local cache.","solutions":["Verify segment integrity (re-download/re-pull the segment from deep storage)","Re-ingest the affected segments so they are written in the current format","Upgrade Druid if the segments were written by a newer format than the reader supports"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"// check segment descriptor/version metadata before loading legacy metric columns\nif (!segmentVersion.equals(\"v8-compatible\")) { re-ingest; }","typeGuard":null,"tryCatchPattern":"try { MetricHolder.fromByteBuffer(buf); } catch (ISE e) { if (e.getMessage().contains(\"Unknown version\")) { /* quarantine/re-download segment */ } else throw e; }","preventionTips":["Keep all Druid nodes on the same version","Validate segment checksums after copying between clusters","Re-ingest segments written by very old formats"],"tags":["druid","segment-format","version-mismatch"],"backgroundTag":"schema-validation-failed","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}