apache/druid · error · IllegalStateException

String is not a metric column type

Error message

String is not a metric column type

What it means

IncrementalIndex's metric column selector factory throws IllegalStateException('String is not a metric column type') when a column declared as a metric has STRING capabilities. Metrics must be numeric (long/float/double) or complex; a string-typed metric indicates the schema mislabels a dimension as a metric.

Source

Thrown at processing/src/main/java/org/apache/druid/segment/incremental/IncrementalIndex.java:793

      String metric
  )
  {
    final MetricDesc metricDesc = rowSelector.getMetric(metric);
    if (metricDesc == null) {
      return NilColumnValueSelector.instance();
    }
    int metricIndex = metricDesc.getIndex();
    switch (metricDesc.getCapabilities().getType()) {
      case COMPLEX:
        return new ObjectMetricColumnSelector(rowSelector, currEntry, metricDesc);
      case LONG:
        return new LongMetricColumnSelector(rowSelector, currEntry, metricIndex);
      case FLOAT:
        return new FloatMetricColumnSelector(rowSelector, currEntry, metricIndex);
      case DOUBLE:
        return new DoubleMetricColumnSelector(rowSelector, currEntry, metricIndex);
      case STRING:
        throw new IllegalStateException("String is not a metric column type");
      default:
        throw new ISE("Unknown metric value type: %s", metricDesc.getCapabilities().getType());
    }
  }

  public Interval getInterval()
  {
    DateTime min = DateTimes.utc(minTimestamp);
    return new Interval(min, isEmpty() ? min : queryGranularity.increment(DateTimes.utc(getMaxTimeMillis())));
  }

  @Nullable
  public DateTime getMinTime()
  {
    return isEmpty() ? null : DateTimes.utc(getMinTimeMillis());
  }

  @Nullable

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Remove the string column from metricsSpec or declare it in the dimensionsSpec instead
  2. Use a proper numeric/complex aggregator for metric columns
  3. Check capabilities: assert getType() != ValueType.STRING before treating a column as a metric

Example fix

// before
"metricsSpec": [{"type": "string", "name": "country"}] // invalid
// after
"metricsSpec": [{"type": "doubleSum", "name": "revenue", "fieldName": "revenue"}]
// and move "country" to dimensionsSpec
Defensive patterns

Strategy: validation

Validate before calling

if (capabilities.getType() == ValueType.STRING) { throw new IllegalArgumentException("Column " + name + " is a dimension, not a metric"); }

Try / catch

try { selector = index.makeColumnValueSelector(...); } catch (IllegalStateException e) { if (e.getMessage().contains("String is not a metric column type")) { throw new IllegalStateException("metricsSpec mislabels a string column as metric", e); } throw e; }

Prevention

When it happens

Trigger: Constructing or querying an IncrementalIndex whose metricsSpec includes a metric of type 'string', or where column capabilities resolve the metric column to STRING.

Common situations: ingestion spec metricsSpec listing a dimension (e.g. a string aggregator name) as a metric; schema/rollup mistakes after changing a column from dimension to metric; typos in aggregator type names causing fallback to string type.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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