apache/druid · warning

Unknown column type for column

Error message

Unknown column type for column[%s]

What it means

SegmentAnalyzer.analyze could not determine the capabilities (type) of a column while building segment metadata (e.g. for a segmentMetadata/SELECT metadata query). Instead of failing the query, it logs a warning and records a ColumnAnalysis with error 'unknown_type' for that column. This typically means the column exists but its type cannot be resolved from the column capabilities.

Solutions

  1. Re-index/re-ingest the affected segment so columns carry proper capabilities
  2. Check which extension/data format produced the segment and upgrade it
  3. Ignore the column's stats — the query still returns other column analyses
  4. Compare Druid versions of the segment and the cluster (version mismatch in segment format)

Example fix

null
Defensive patterns

Strategy: validation

Validate before calling

ColumnCapabilities caps = column.getColumnCapabilities(name);
if (caps == null || caps.getType() == null) { /* skip analysis or re-index segment */ }

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: A segmentMetadata or schema-rolling query hits a segment whose column has null capabilities, e.g. metadata-less segments, unsupported/legacy column formats, or columns added via a handler that does not report capabilities.

Common situations: Older segments created before a type was introduced, third-party extensions producing columns without capabilities, schema rollup ingestion leaving columns untyped.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/096b26eb5806d499. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/query/metadata/SegmentAnalyzer.java:116

    final CursorFactory cursorFactory = Objects.requireNonNull(segment.as(CursorFactory.class));

    final int numRows = rowCountInspector != null ? rowCountInspector.getNumRows() : 0;

    // Use LinkedHashMap to preserve column order.
    final Map<String, ColumnAnalysis> columns = new LinkedHashMap<>();

    final RowSignature rowSignature = cursorFactory.getRowSignature();
    for (String columnName : rowSignature.getColumnNames()) {
      final ColumnCapabilities capabilities;

      if (columnInspector != null) {
        capabilities = columnInspector.getColumnCapabilities(columnName);
      } else {
        capabilities = null;
      }

      if (capabilities == null) {
        log.warn("Unknown column type for column[%s]", columnName);
        columns.put(columnName, ColumnAnalysis.error("unknown_type"));
        continue;
      }

      ColumnAnalysis analysis;
      try {
        switch (capabilities.getType()) {
          case LONG:
            final int bytesPerRow =
                ColumnHolder.TIME_COLUMN_NAME.equals(columnName) ? NUM_BYTES_IN_TIMESTAMP : Long.BYTES;

            analysis = analyzeNumericColumn(capabilities, numRows, bytesPerRow);
            break;
          case FLOAT:
            analysis = analyzeNumericColumn(capabilities, numRows, NUM_BYTES_IN_TEXT_FLOAT);
            break;
          case DOUBLE:
            analysis = analyzeNumericColumn(capabilities, numRows, Double.BYTES);

View on GitHub (pinned to 9b90983fd2)