apache/druid · error · org.apache.druid.java.util.common.IAE

maxStringBytes must be greater than 0

Error message

maxStringBytes must be greater than 0

What it means

StringFirstAggregatorFactory validates maxStringBytes in its constructor: a non-null negative value is rejected with this IllegalArgumentException (via Preconditions/IAE). The message is slightly misleading — the check actually rejects negative values; only non-negative values pass. It protects the aggregator's string-chopping logic from nonsense bounds.

Solutions

  1. Set maxStringBytes to a positive integer (or omit/null it to use the default 1023).
  2. If the intent was unlimited, remove the field rather than passing a negative sentinel.
  3. Fix the producing code/config generator so it emits null or a positive value instead of -1.
  4. Re-validate the query spec JSON before submission.

Example fix

// before
{"type":"stringFirst","name":"s","fieldName":"col","maxStringBytes":-1}
// after
{"type":"stringFirst","name":"s","fieldName":"col"}
Defensive patterns

Strategy: validation

Validate before calling

if (maxStringBytes != null && maxStringBytes < 0) {
  throw new IllegalArgumentException("maxStringBytes must be >= 0");
}
new StringFirstAggregatorFactory(name, field, null, maxStringBytes);

Try / catch

try {
  factory = mapper.readValue(spec, StringFirstAggregatorFactory.class);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("maxStringBytes")) {
    throw new QuerySpecValidationException("maxStringBytes must be a non-negative integer");
  }
  throw e;
}

Prevention

When it happens

Trigger: Constructing StringFirstAggregatorFactory (directly in Java or via JSON deserialization of a native query spec) with maxStringBytes set to a negative number.

Common situations: Hand-written query JSON with maxStringBytes: -1 intending 'unlimited'; config generated programmatically with a sentinel -1; copy-paste from code that used -1 as a default elsewhere.

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/0d571552355a0fea. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/query/aggregation/firstlast/first/StringFirstAggregatorFactory.java:146

  private final String fieldName;
  private final String name;
  private final String timeColumn;
  protected final int maxStringBytes;

  @JsonCreator
  public StringFirstAggregatorFactory(
      @JsonProperty("name") String name,
      @JsonProperty("fieldName") final String fieldName,
      @JsonProperty("timeColumn") @Nullable final String timeColumn,
      @JsonProperty("maxStringBytes") Integer maxStringBytes
  )
  {
    Preconditions.checkNotNull(name, "Must have a valid, non-null aggregator name");
    Preconditions.checkNotNull(fieldName, "Must have a valid, non-null fieldName");

    if (maxStringBytes != null && maxStringBytes < 0) {
      throw new IAE("maxStringBytes must be greater than 0");
    }

    this.name = name;
    this.fieldName = fieldName;
    this.timeColumn = timeColumn == null ? ColumnHolder.TIME_COLUMN_NAME : timeColumn;
    this.maxStringBytes = maxStringBytes == null
                          ? StringFirstAggregatorFactory.DEFAULT_MAX_STRING_SIZE
                          : maxStringBytes;
  }


  @Override
  public Aggregator factorize(ColumnSelectorFactory metricFactory)
  {
    final BaseObjectColumnValueSelector<?> valueSelector = metricFactory.makeColumnValueSelector(fieldName);
    if (valueSelector instanceof NilColumnValueSelector) {
      return NIL_AGGREGATOR;
    } else {

View on GitHub (pinned to 9b90983fd2)