apache/druid · error · IllegalStateException
Failed to add a row with timestamp[%s]
Error message
Failed to add a row with timestamp[%s]
What it means
Thrown by SinglePhaseSubTask.generateAndPushSegments when the IndexIngestionDriver fails to add an input row to the current segment — i.e., the row could not be added to the incremental index while building segments. This indicates a row-level ingestion failure such as the row not fitting into the current segment's schema/partitioning, rather than bad input alone, and Druid surfaces the failing row's timestamp for diagnosis.
Source
Thrown at indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/SinglePhaseSubTask.java:444
if (addResult.isOk()) {
final boolean isPushRequired = addResult.isPushRequired(
partitionsSpec.getMaxRowsPerSegment(),
partitionsSpec.getMaxTotalRowsOr(DynamicPartitionsSpec.DEFAULT_MAX_TOTAL_ROWS)
);
if (isPushRequired) {
// There can be some segments waiting for being published even though any rows won't be added to them.
// If those segments are not published here, the available space in appenderator will be kept to be small
// which makes the size of segments smaller.
final SegmentsAndCommitMetadata pushed = driver.pushAllAndClear(pushTimeout);
pushedSegments.addAll(pushed.getSegments());
segmentSchemaMapping.merge(pushed.getSegmentSchemaMapping());
LOG.info("Pushed [%s] segments and [%s] schemas", pushed.getSegments().size(), segmentSchemaMapping.getSchemaCount());
LOG.infoSegments(pushed.getSegments(), "Pushed segments");
LOG.info("SegmentSchema is [%s]", segmentSchemaMapping);
}
} else {
throw new ISE("Failed to add a row with timestamp[%s]", inputRow.getTimestamp());
}
}
final SegmentsAndCommitMetadata pushed = driver.pushAllAndClear(pushTimeout);
pushedSegments.addAll(pushed.getSegments());
segmentSchemaMapping.merge(pushed.getSegmentSchemaMapping());
LOG.info("Pushed [%s] segments and [%s] schemas", pushed.getSegments().size(), segmentSchemaMapping.getSchemaCount());
LOG.infoSegments(pushed.getSegments(), "Pushed segments");
LOG.info("SegmentSchema is [%s]", segmentSchemaMapping);
appenderator.close();
return new DataSegmentsWithSchemas(pushedSegments, segmentSchemaMapping.isNonEmpty() ? segmentSchemaMapping : null);
}
catch (TimeoutException | ExecutionException e) {
exceptionOccurred = true;
throw new RuntimeException(e);
}
catch (Exception e) {View on GitHub (pinned to 9b90983fd2)
Solutions
- Check the reported timestamp and the subtask's assigned intervals/partitions; fix the input filter or partitionsSpec so rows match the subtask's ranges
- Re-run determinePartitions to regenerate partition boundaries if input data shifted between the determine and ingest phases
- Verify that clocks and time filtering in the input source do not emit rows outside the task granularity interval
- If caused by a driver/index bug, capture the failing row and report with full task logs; consider upgrading Druid
Example fix
// before: rows outside assigned range reach the driver
InputRow row = rowIterator.next();
// after: pre-filter to the subtask's interval/partition range
if (interval.contains(row.getTimestamp()) && range.contains(row.getDimension(partitionDim).get(0))) {
driver.add(row);
} Defensive patterns
Strategy: validation
Validate before calling
// pre-filter rows to the subtask's assigned interval and partition range before driver.add
if (!interval.contains(inputRow.getTimestamp())) { continue; }
Object pdv = inputRow.getRaw(partitionDimension);
if (!assignedRange.contains(pdv)) { continue; } Type guard
boolean isRowInScope(InputRow row, Interval interval, Range<Object> range, String dim) {
return interval.contains(row.getTimestamp())
&& row.getDimension(dim) != null
&& row.getDimension(dim).size() == 1
&& range.contains(row.getDimension(dim).get(0));
} Try / catch
catch (ISE e) {
if (e.getMessage().startsWith("Failed to add a row with timestamp")) {
log.error("row out of segment scope at %s; check partitionsSpec/interval filters", e.getMessage());
throw new TaskRetryableException(e); // or fail fast with diagnostics
} throw e;
} Prevention
- Run the input-source sampler to verify rows match the configured intervals
- Keep partitionsSpec boundaries and input data in sync: re-run determinePartitions if data changed
- NTP-sync cluster clocks so timestamps stay inside task intervals
- Flatten multi-valued partition dimensions before ingestion
When it happens
Trigger: driver.add(inputRow) returns false (row not added) — e.g., the row's dimensions/timestamp fall outside the shard spec's expected range for the current segment, or the incremental index rejects the row because of schema mismatch with the assigned partition.
Common situations: Range partitioning where a row's partition-dimension value doesn't match the subtask's assigned range; clock issues putting rows outside the task's interval; dimension schema changes mid-run; rows filtered by partitions but not pre-filtered by the input source reader.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Can't find previous segmentIds for sequence[%s]
- Can't find previously allocated segmentId[%s] for sequence[%
- ColumnCapacityExceededException
- Bloom filter aggregators are query-time only
- Unsupported keyFormat. KafkaInputformat only supports input
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/3c944d96929a5312.
Report an issue: GitHub.