apache/druid · error · IllegalStateException
Illegal segmentId format [%s]
Error message
Illegal segmentId format [%s]
What it means
Thrown by SinglePhaseParallelIndexTaskRunner.allocateNewSegment when SegmentId.tryParse fails to parse the stored next-segment-ID string from the sequence's allocation list. Segment IDs in the allocation state are expected to be parseable 'dataSource_interval_version_partition' strings; an unparseable value means the stored allocation state is corrupt or was written by incompatible code.
Source
Thrown at indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/SinglePhaseParallelIndexTaskRunner.java:244
if (prevSegmentId == null) {
prevSegmentIdIndex = -1;
segmentIds = v == null ? new ArrayList<>() : v;
} else {
segmentIds = v;
if (segmentIds == null) {
throw new ISE("Can't find previous segmentIds for sequence[%s]", sequenceName);
}
prevSegmentIdIndex = segmentIds.indexOf(prevSegmentId);
if (prevSegmentIdIndex == -1) {
throw new ISE("Can't find previously allocated segmentId[%s] for sequence[%s]", prevSegmentId, sequenceName);
}
}
final int nextSegmentIdIndex = prevSegmentIdIndex + 1;
final SegmentIdWithShardSpec newSegmentId;
if (nextSegmentIdIndex < segmentIds.size()) {
SegmentId segmentId = SegmentId.tryParse(dataSource, segmentIds.get(nextSegmentIdIndex));
if (segmentId == null) {
throw new ISE("Illegal segmentId format [%s]", segmentIds.get(nextSegmentIdIndex));
}
newSegmentId = new SegmentIdWithShardSpec(
segmentId.getDataSource(),
segmentId.getInterval(),
segmentId.getVersion(),
new BuildingNumberedShardSpec(segmentId.getPartitionNum())
);
} else {
final int partitionNum = Counters.getAndIncrementInt(partitionNumCountersPerInterval, intervalAndVersion.lhs);
newSegmentId = new SegmentIdWithShardSpec(
dataSource,
intervalAndVersion.lhs,
intervalAndVersion.rhs,
new BuildingNumberedShardSpec(partitionNum)
);
segmentIds.add(newSegmentId.toString());
}
segmentIdHolder.setValue(newSegmentId);View on GitHub (pinned to 9b90983fd2)
Solutions
- Restart/resubmit the supervisor task to rebuild the allocation list from scratch
- Inspect the stored segmentIds (overlord logs / task storage) to find the malformed entry and its origin
- Verify all Druid nodes and extensions run the same version
- If state is persisted in an external metadata store, clean the corrupt rows for this task and retry
Example fix
// before: unvalidated stored ID passed to tryParse
SegmentId segmentId = SegmentId.tryParse(dataSource, segmentIds.get(nextSegmentIdIndex));
// after: validate format before storing
String id = segmentIds.get(nextSegmentIdIndex);
if (!SEGMENT_ID_PATTERN.matcher(id).matches()) { log.warn("dropping malformed id %s", id); } Defensive patterns
Strategy: validation
Validate before calling
// validate stored segment IDs parse before use
for (String id : segmentIds) {
if (SegmentId.tryParse(dataSource, id) == null) {
throw new IllegalStateException("corrupt allocation entry: " + id);
}
} Type guard
static boolean isParseableSegmentId(String dataSource, String id) {
return id != null && SegmentId.tryParse(dataSource, id) != null;
} Try / catch
catch (ISE e) {
if (e.getMessage().startsWith("Illegal segmentId format")) {
log.error("corrupt allocation state: %s", e.getMessage());
resubmitSupervisor(taskSpec); // rebuild state
} else throw e;
} Prevention
- Keep all nodes/extensions on one Druid version during long-running batch tasks
- Never hand-edit task allocation state in the metadata store
- Validate metadata store backups before restoring them into a live cluster
When it happens
Trigger: The segmentIds list for a sequence contains a malformed entry (e.g., manually edited task state, corrupted metadata, or an ID written by a different Druid version with an incompatible format) and nextSegmentIdIndex points at it.
Common situations: Upgrading Druid across versions while a batch task's state persists; restoring task state from backups; custom extensions writing non-standard segment IDs into allocation maps.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Could not find interval for timestamp [%s]
- Can't find previously allocated segmentId[%s] for sequence[%
- Unable to parse row [%s]
- Unable to parse row [%s]
- JavaScript parsed value [%s] must be in {key: value} format!
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/7253d8daa8f063e4.
Report an issue: GitHub.