{"record":{"id":"7253d8daa8f063e4","repo":"apache/druid","slug":"illegal-segmentid-format-s","errorCode":null,"errorMessage":"Illegal segmentId format [%s]","messagePattern":"Illegal segmentId format \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/SinglePhaseParallelIndexTaskRunner.java","lineNumber":244,"sourceCode":"      if (prevSegmentId == null) {\n        prevSegmentIdIndex = -1;\n        segmentIds = v == null ? new ArrayList<>() : v;\n      } else {\n        segmentIds = v;\n        if (segmentIds == null) {\n          throw new ISE(\"Can't find previous segmentIds for sequence[%s]\", sequenceName);\n        }\n        prevSegmentIdIndex = segmentIds.indexOf(prevSegmentId);\n        if (prevSegmentIdIndex == -1) {\n          throw new ISE(\"Can't find previously allocated segmentId[%s] for sequence[%s]\", prevSegmentId, sequenceName);\n        }\n      }\n      final int nextSegmentIdIndex = prevSegmentIdIndex + 1;\n      final SegmentIdWithShardSpec newSegmentId;\n      if (nextSegmentIdIndex < segmentIds.size()) {\n        SegmentId segmentId = SegmentId.tryParse(dataSource, segmentIds.get(nextSegmentIdIndex));\n        if (segmentId == null) {\n          throw new ISE(\"Illegal segmentId format [%s]\", segmentIds.get(nextSegmentIdIndex));\n        }\n        newSegmentId = new SegmentIdWithShardSpec(\n            segmentId.getDataSource(),\n            segmentId.getInterval(),\n            segmentId.getVersion(),\n            new BuildingNumberedShardSpec(segmentId.getPartitionNum())\n        );\n      } else {\n        final int partitionNum = Counters.getAndIncrementInt(partitionNumCountersPerInterval, intervalAndVersion.lhs);\n        newSegmentId = new SegmentIdWithShardSpec(\n            dataSource,\n            intervalAndVersion.lhs,\n            intervalAndVersion.rhs,\n            new BuildingNumberedShardSpec(partitionNum)\n        );\n        segmentIds.add(newSegmentId.toString());\n      }\n      segmentIdHolder.setValue(newSegmentId);","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/SinglePhaseParallelIndexTaskRunner.java#L226-L262","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: unvalidated stored ID passed to tryParse\nSegmentId segmentId = SegmentId.tryParse(dataSource, segmentIds.get(nextSegmentIdIndex));\n// after: validate format before storing\nString id = segmentIds.get(nextSegmentIdIndex);\nif (!SEGMENT_ID_PATTERN.matcher(id).matches()) { log.warn(\"dropping malformed id %s\", id); }","handlingStrategy":"validation","validationCode":"// validate stored segment IDs parse before use\nfor (String id : segmentIds) {\n  if (SegmentId.tryParse(dataSource, id) == null) {\n    throw new IllegalStateException(\"corrupt allocation entry: \" + id);\n  }\n}","typeGuard":"static boolean isParseableSegmentId(String dataSource, String id) {\n  return id != null && SegmentId.tryParse(dataSource, id) != null;\n}","tryCatchPattern":"catch (ISE e) {\n  if (e.getMessage().startsWith(\"Illegal segmentId format\")) {\n    log.error(\"corrupt allocation state: %s\", e.getMessage());\n    resubmitSupervisor(taskSpec); // rebuild state\n  } else throw e;\n}","preventionTips":["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"],"tags":["ingestion","segment-allocation","parsing"],"backgroundTag":"invalid-identifier-format","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}