{"record":{"id":"bc3cad96fe8b7177","repo":"apache/druid","slug":"failed-to-get-shardspec-for-interval-s","errorCode":null,"errorMessage":"Failed to get shardSpec for interval[%s]","messagePattern":"Failed to get shardSpec for interval\\[(.+?)\\]","errorType":"exception","errorClass":"ISE","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/common/task/ShardSpecs.java","lineNumber":57,"sourceCode":"  ShardSpecs(final Map<Interval, List<BucketNumberedShardSpec<?>>> map, Granularity queryGranularity)\n  {\n    this.map = map;\n    this.queryGranularity = queryGranularity;\n  }\n\n  /**\n   * Return a shardSpec for the given interval and input row.\n   *\n   * @param interval interval for shardSpec\n   * @param row      input row\n   *\n   * @return a shardSpec\n   */\n  BucketNumberedShardSpec<?> getShardSpec(Interval interval, InputRow row)\n  {\n    final List<BucketNumberedShardSpec<?>> shardSpecs = map.get(interval);\n    if (shardSpecs == null || shardSpecs.isEmpty()) {\n      throw new ISE(\"Failed to get shardSpec for interval[%s]\", interval);\n    }\n    final long truncatedTimestamp = queryGranularity.bucketStart(row.getTimestamp()).getMillis();\n    return (BucketNumberedShardSpec<?>) shardSpecs.get(0).getLookup(shardSpecs).getShardSpec(truncatedTimestamp, row);\n  }\n}\n","sourceCodeStart":39,"sourceCodeEnd":63,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/common/task/ShardSpecs.java#L39-L63","documentation":"ShardSpecs maintains a map of intervals to lists of BucketNumberedShardSpec produced during determineShardSpecs. getShardSpec looks up the shard specs for the row's interval and throws ISE when no shard specs were computed for that interval, meaning the row's timestamp bucket was never part of the shard-spec planning phase.","triggerScenarios":"Calling getShardSpec(interval, row) with an interval that is absent from the map — typically because the input row's timestamp, truncated to queryGranularity, falls into an interval for which no shard specs were determined (e.g. rows outside the configured granularity/intervals of the task), or getShardSpec is invoked before determineShardSpecs populated the map.","commonSituations":"Ingesting rows whose timestamps fall outside the task's configured intervals (late-arriving or mistimed data with fixOffsetsTimestampGranularity disabled); custom tasks calling getShardSpec against a partially built ShardSpecs map; clock-skewed producers emitting timestamps in unexpected buckets.","solutions":["Check the offending row's timestamp and the task's granularitySpec intervals; ensure rows fall within configured intervals or enable dropRowOnOutOfInterval / widen the intervals.","Re-run shard-spec determination (determineShardSpecs) before reading rows so the map is fully populated.","Verify queryGranularity matches the data — rows bucketed to a granularity not covered by the shard specs plan will have no entry.","Filter or route out-of-range rows before indexing instead of letting them reach getShardSpec."],"exampleFix":"// before\nBucketNumberedShardSpec<?> spec = shardSpecs.getShardSpec(interval, row); // ISE if interval unplanned\n// after\nif (!shardSpecs.hasShardSpec(interval)) {\n  log.warn(\"Dropping row outside planned intervals: %s\", row);\n  return null;\n}\nBucketNumberedShardSpec<?> spec = shardSpecs.getShardSpec(interval, row);","handlingStrategy":"validation","validationCode":"if (rows.stream().map(r -> gran.bucketStart(r.getTimestamp())).anyMatch(t -> !plannedIntervals.contains(new Interval(t, gran)))) {\n  throw new IllegalArgumentException(\"Rows exist outside planned shard-spec intervals\");\n}","typeGuard":"boolean isPlanned(ShardSpecs specs, Interval interval) { return specs != null && specs.getShardSpecsForInterval(interval) != null && !specs.getShardSpecsForInterval(interval).isEmpty(); }","tryCatchPattern":"try {\n  return shardSpecs.getShardSpec(interval, row);\n} catch (IllegalStateException e) {\n  if (e.getMessage().startsWith(\"Failed to get shardSpec\")) {\n    log.debug(\"Row outside planned intervals, dropping: %s\", row.getId());\n    return null;\n  }\n  throw e;\n}","preventionTips":["Ensure input timestamps fall within the task's granularitySpec intervals","Enable dropping of out-of-interval rows before the shard-spec phase","Keep queryGranularity consistent between shard-spec determination and row processing","Run determineShardSpecs before any per-row getShardSpec calls"],"tags":["druid","sharding","batch-indexing","timestamps"],"backgroundTag":"resource-not-found","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}