apache/druid · error · IllegalArgumentException
replaceTimeChunks must be null or nonempty; cannot be empty
Error message
replaceTimeChunks must be null or nonempty; cannot be empty
What it means
Validation in validateReplaceTimeChunksGranularityAligned: for MSQ REPLACE queries, replaceTimeChunks may be omitted entirely (null) to replace everything, or list specific time chunks to replace — but an empty list is ambiguous and therefore rejected at destination-construction time before any work is done.
Solutions
- Remove the replaceTimeChunks clause entirely from the REPLACE SQL to replace all time chunks.
- Provide at least one explicit time chunk interval (e.g. replaceTimeChunks = [2024-01-01/2024-02-01]) if a partial replace is intended.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/indexing/destination/DataSourceMSQDestination.java:276 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/18f37fa9d080a327.
Report an issue: GitHub.
Appendix: source
Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/indexing/destination/DataSourceMSQDestination.java:276
{
return ShuffleSpecFactories.globalSortWithTargetSize(targetSize);
}
@Override
public Optional<Resource> getDestinationResource()
{
return Optional.of(new Resource(getDataSource(), ResourceType.DATASOURCE));
}
private static void validateReplaceTimeChunksGranularityAligned(
Granularity segmentGranularity,
@Nullable List<Interval> replaceTimeChunks
)
{
if (replaceTimeChunks != null) {
// Verify that if replaceTimeChunks is provided, it is nonempty.
if (replaceTimeChunks.isEmpty()) {
throw new IAE("replaceTimeChunks must be null or nonempty; cannot be empty");
}
// Verify all provided time chunks are aligned with segmentGranularity.
for (final Interval interval : replaceTimeChunks) {
// ETERNITY gets a free pass.
if (!Intervals.ETERNITY.equals(interval)) {
final boolean startIsAligned =
segmentGranularity.bucketStart(interval.getStart()).equals(interval.getStart());
final boolean endIsAligned =
segmentGranularity.bucketStart(interval.getEnd()).equals(interval.getEnd())
|| segmentGranularity.increment(segmentGranularity.bucketStart(interval.getEnd()))
.equals(interval.getEnd());
if (!startIsAligned || !endIsAligned) {
throw new IAE(
"Time chunk [%s] provided in replaceTimeChunks is not aligned with segmentGranularity [%s]",
interval,View on GitHub (pinned to 9b90983fd2)