apache/druid · error · IllegalArgumentException

Output type[%s] must be numeric

Error message

Output type[%s] must be numeric

What it means

Rows.objectToNumber validates that the requested outputType is a numeric ValueType (LONG, FLOAT, DOUBLE) before converting a field value to a Number. Druid throws this IllegalArgumentException immediately when a caller passes a non-numeric output type such as STRING or COMPLEX, because the method's contract is to produce numbers only. It is a programming/API misuse error, not a data error.

Source

Thrown at processing/src/main/java/org/apache/druid/data/input/Rows.java:122

   * @param inputValue           the actual object being converted
   * @param outputType           expected return type, or null if it should be automatically detected
   * @param throwParseExceptions whether this method should throw a {@link ParseException} or use a default/null value
   *                             when {@param inputValue} is not numeric
   *
   * @return a Number; will not necessarily be the same type as {@param zeroClass}
   *
   * @throws ParseException if the input cannot be converted to a number and {@code throwParseExceptions} is true
   */
  @Nullable
  public static Number objectToNumber(
      final String name,
      final Object inputValue,
      @Nullable final ValueType outputType,
      final boolean throwParseExceptions
  )
  {
    if (outputType != null && !outputType.isNumeric()) {
      throw new IAE("Output type[%s] must be numeric", outputType);
    }

    final Number asNumber;

    if (inputValue == null) {
      asNumber = null;
    } else if (inputValue instanceof Number) {
      asNumber = (Number) inputValue;
    } else if (inputValue instanceof String) {
      try {
        String metricValueString = StringUtils.removeChar(((String) inputValue).trim(), ',');
        // Longs.tryParse() doesn't support leading '+', so we need to trim it ourselves
        metricValueString = trimLeadingPlusOfLongString(metricValueString);

        Number v = null;

        // Try parsing as Long first, since it's significantly faster than Double parsing, and also there are various
        // integer numbers that can be represented as Long but cannot be represented as Double.

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Change the outputType argument to a numeric ValueType: ValueType.LONG, ValueType.FLOAT, or ValueType.DOUBLE.
  2. Pass null for outputType to have Druid auto-detect the numeric type from the input value.
  3. If a string is genuinely needed, use Rows.objectToStrings instead of objectToNumber.

Example fix

// before
Number n = Rows.objectToNumber("metric", inputValue, ValueType.STRING, true);
// after
Number n = Rows.objectToNumber("metric", inputValue, ValueType.DOUBLE, true);
Defensive patterns

Strategy: type-guard

Validate before calling

if (outputType != null && !outputType.isNumeric()) {
  throw new IllegalArgumentException("outputType must be numeric: " + outputType);
}

Type guard

boolean isNumericOutput(@Nullable ValueType t) {
  return t == null || t == ValueType.LONG || t == ValueType.FLOAT || t == ValueType.DOUBLE;
}

Try / catch

try {
  return Rows.objectToNumber(name, value, outputType, true);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("must be numeric")) {
    outputType = null; // fall back to auto-detect
    return Rows.objectToNumber(name, value, null, true);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling Rows.objectToNumber(name, inputValue, ValueType.STRING, true) (or any non-numeric ValueType) directly; passing a column type expression or metric type spec that resolves to a non-numeric ValueType into a numeric aggregator/extraction path that delegates to objectToNumber.

Common situations: Aggregator specs where the type is mistakenly set to "string" while using floatSum/longSum style aggregation; custom code copying the 3-arg overload and adding an explicit outputType; type specs auto-derived from a dimension whose type was configured incorrectly.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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