apache/druid · error · ParseException

Could not convert value [%s] to long for dimension [%s]. Inv

Error message

Could not convert value [%s] to long for dimension [%s]. Invalid type: [%s]

What it means

convertObjectToLong throws this ParseException when the value's Java type is not one it can convert to long (not Number, not String, not List — e.g. a Map, boolean, or nested object). The message includes the value's actual class so the offending type is visible.

Source

Thrown at processing/src/main/java/org/apache/druid/segment/DimensionHandlerUtils.java:443

      );
    } else {
      final String message;
      if (objectKey != null) {
        message = StringUtils.nonStrictFormat(
            "Could not convert value [%s] to long for dimension [%s]. Invalid type: [%s]",
            valObj,
            objectKey,
            valObj.getClass()
        );
      } else {
        message = StringUtils.nonStrictFormat(
            valObj.getClass().toString(),
            "Could not convert value [%s] to long. Invalid type: [%s]",
            valObj,
            valObj.getClass()
        );
      }
      throw new ParseException(
          valObj.getClass().toString(),
          message
      );
    }
  }

  @Nullable
  public static Long convertObjectToLong(@Nullable Object valObj)
  {
    return convertObjectToLong(valObj, false);
  }

  @Nullable
  public static Long convertObjectToLong(@Nullable Object valObj, boolean reportParseExceptions)
  {
    return convertObjectToLong(valObj, reportParseExceptions, null);
  }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Fix upstream data so the field is always a number or numeric string for long columns.
  2. Add an ingest-time transform to extract the numeric field from the nested object before conversion.
  3. Change the column's declared type to string (or use nested column support) if the value is genuinely structured.
  4. Validate input schema with a JSON schema / sample-data check in the ingestion spec wizard before publishing.

Example fix

// before: long column receives {"amount": 5}
// after: transform extracts the nested number
"transforms": [{"type": "expression", "name": "amount", "expression": "CAST(json_value(payload, '$.amount') AS LONG)"}]
Defensive patterns

Strategy: type-guard

Validate before calling

boolean convertibleToLong(Object v) {
  return v == null || v instanceof Number || v instanceof String;
}

Type guard

Long asLong(Object v) {
  if (v instanceof Number) return ((Number) v).longValue();
  if (v instanceof String) { try { return Long.parseLong((String) v); } catch (NumberFormatException e) { return null; } }
  return null;
}

Try / catch

try {
  return DimensionHandlerUtils.convertObjectToLong(value, fieldName, objectKey);
} catch (ParseException e) {
  log.warn("Invalid type [%s] for long field [%s], dropping", value.getClass(), fieldName);
  return null;
}

Prevention

When it happens

Trigger: A long column receives a value of an unhandled runtime type — e.g. a JSON object (Map) or boolean — so the final else branch in convertObjectToLong fires; also reached via convertObjectToType.

Common situations: JSON input with nested objects mapped to a long column; schema drift where a field changes from number to object/array upstream; auto type detection picking long for a heterogeneous field.

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/9e2a6025a14ac184. Report an issue: GitHub.