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
- Set maxStringBytes to a positive integer (or omit/null it to use the default 1023).
- If the intent was unlimited, remove the field rather than passing a negative sentinel.
- Fix the producing code/config generator so it emits null or a positive value instead of -1.
- 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
- Never use -1 as an 'unlimited' sentinel for maxStringBytes.
- Omit the field to use the default (1023).
- Validate query JSON with the schema before submission.
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
- Compression value [ ] is greater than the max allowed…
- Aggregation [ ] does not support column [ ] of type [ ]…
- Aggregator[ ] cannot vectorize
- AggregatorFactoryNotMergeableException
- AggregatorFactoryNotMergeableException
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)