{"record":{"id":"15be1fb13b8c8b5a","repo":"apache/druid","slug":"unknown-type-s-cannot-load","errorCode":null,"errorMessage":"Unknown type[%s], cannot load.","messagePattern":"Unknown type\\[(.+?)\\], cannot load\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/MetricHolder.java","lineNumber":67,"sourceCode":"    }\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) {\n          throw new ISE(\"Unknown type[%s], cannot load.\", holder.getTypeName());\n        }\n\n        holder.complexType = read(buf, serdeForType);\n        break;\n      case LONG:\n      case DOUBLE:\n        throw new ISE(\"Unsupported type[%s]\", holder.type);\n    }\n\n    return holder;\n  }\n\n  private static <T> GenericIndexed<T> read(ByteBuffer buf, ComplexMetricSerde serde)\n  {\n    return GenericIndexed.read(buf, serde.getObjectStrategy(), null);\n  }\n\n  public enum MetricType","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/MetricHolder.java#L49-L85","documentation":"Also in MetricHolder.fromByteBuffer: after parsing the type name, a COMPLEX metric needs a registered ComplexMetricSerde; if ComplexMetrics.getSerdeForType returns null the loader throws ISE 'Unknown type, cannot load'. The running JVM lacks the serde for that complex metric type.","triggerScenarios":"Loading a legacy segment containing a complex metric (e.g. hyperUnique, sketches) whose extension is not loaded on this node.","commonSituations":"Historical nodes missing extensions that ingestion nodes had; moving segments between clusters with different extension sets; renamed/removed complex metric types across versions.","solutions":["Load the extension providing the serde on the reading node (druid.extensions.loadList)","Align extension configuration across all Druid services","Re-ingest or convert the segment to replace obsolete complex metric types"],"exampleFix":"// before\ndruid.extensions.loadList=[]\n// after\ndruid.extensions.loadList=[\"druid-datasketches\"] // registers serde for the sketch type in the segment","handlingStrategy":"validation","validationCode":"String complexType = holder.getTypeName(); if (ComplexMetrics.getSerdeForType(complexType) == null) { /* load extension or fail fast before reading */ }","typeGuard":"boolean canLoadComplexMetric(String typeName) { return ComplexMetrics.getSerdeForType(typeName) != null; }","tryCatchPattern":"try { MetricHolder.fromByteBuffer(buf); } catch (ISE e) { if (e.getMessage().contains(\"cannot load\")) { /* register missing serde/extension and retry */ } else throw e; }","preventionTips":["Install all extensions referenced by ingested metric types on every node","Use the same extension load list across ingestion and query clusters","Prefer standard sketch extensions (druid-datasketches) over ad-hoc types"],"tags":["druid","complex-metric","missing-serde"],"backgroundTag":"missing-dependency","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"}