apache/druid · error · IllegalArgumentException
Invalid path: [ ], should contain '/
Error message
Invalid path: [%s], should contain '/'
What it means
DataSegmentKiller.descriptorPath derives the descriptor.json location from a segment's storage path by replacing the last path component. If the path contains no '/' separator at all it cannot locate a parent directory, so it throws IAE indicating the path is invalid for descriptor lookup.
Solutions
- Ensure the segment path stored in the metadata store is a full deep-storage path with '/' separators
- Fix the LoadSpec or storage key construction that produced the separator-less path
- Re-upload or repair the segment entry in the segments table with a correct path
Example fix
// before String path = "index.zip"; // no separator String desc = DataSegmentKiller.descriptorPath(path); // throws // after String path = "s3://bucket/druid/segments/ds/2020-01-01/seg/index.zip"; String desc = DataSegmentKiller.descriptorPath(path); // .../seg/descriptor.json
Defensive patterns
Strategy: validation
Validate before calling
if (path == null || !path.contains("/")) throw new IllegalArgumentException("Segment path must be a full deep-storage path: " + path); Type guard
boolean isDeepStoragePath(String p) { return p != null && p.lastIndexOf('/') > 0; } Try / catch
try { String desc = DataSegmentKiller.descriptorPath(path); } catch (IAE e) { log.error("Bad segment path in metadata: %s", path); throw e; } Prevention
- Never hand-edit paths in the segments metadata table
- Validate LoadSpec/storage key formats when writing custom deep storage modules
- Run metadata health checks that assert path shape before cleanup jobs
When it happens
Trigger: Calling DataSegmentKiller APIs (or descriptorPath directly) with a segment storage path lacking any '/', e.g. a bare filename or a misconfigured single-component deep storage key.
Common situations: Custom LoadSpec/UriExtractionStrategy producing paths without separators; hand-editing segment metadata paths; deep storage emulators that flatten keys.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- A-Not-B requires at least 1 sketch
- BloomKFilters are not compatible for merging. this
- Bucket index out of range (0, )
- Caching is not supported. Check `isCacheable` before…
- Cannot add files of the same name, already have
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/b49646c8db52c48a.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/loading/DataSegmentKiller.java:46
import java.util.List;
/**
* DataSegmentKiller knows how to kill segments from the Druid system.
* Since any implementation of DataSegmentKiller is initialized when an ingestion job starts
* if a deep storage extension is loaded even when that deep storage is actually not used,
* implementations should avoid initializing the deep storage client immediately
* but defer it until the deep storage client is actually used.
*/
@ExtensionPoint
public interface DataSegmentKiller
{
Logger log = new Logger(DataSegmentKiller.class);
static String descriptorPath(String path)
{
int lastPathSeparatorIndex = path.lastIndexOf('/');
if (lastPathSeparatorIndex == -1) {
throw new IAE("Invalid path: [%s], should contain '/'", path);
}
return path.substring(0, lastPathSeparatorIndex) + "/descriptor.json";
}
/**
* Removes segment files (index and metadata) from deep storage.
* @param segment the segment to kill
* @throws SegmentLoadingException if the segment could not be completely removed
*/
void kill(DataSegment segment) throws SegmentLoadingException;
/**
* Kills a list of segments from deep storage. The default implementation calls kill on the segments in a loop.
* Implementers of this interface can leverage batch / bulk deletes to be more efficient. It is preferable to attempt
* to delete all segments even if there is an issue with deleting a single one. This is up to implementers to
* implement as putting a try catch around the default kill via iteration can be problematic if the client of the deep
* storage is unable to authenticate itself and segment loading exception doesn't encode enough information in it to \
* understand why it failed.View on GitHub (pinned to 9b90983fd2)