apache/druid · error · IAE
Don't know how to load SCHEME [%s] for URI [%s]
Error message
Don't know how to load SCHEME [%s] for URI [%s]
What it means
HdfsDataSegmentPuller.getInputStream() only knows how to read segments stored on HDFS. When the URI's scheme is not 'hdfs' it refuses to proceed, throwing this IllegalArgumentException before touching the filesystem. It guards against misconfigured deep-storage URIs being handed to the HDFS puller.
Source
Thrown at extensions-core/hdfs-storage/src/main/java/org/apache/druid/storage/hdfs/HdfsDataSegmentPuller.java:317
if (emitter == null) {
return;
}
ServiceMetricEvent.Builder metricBuilder = ServiceMetricEvent.builder();
metricBuilder.setDimension("format", format);
emitter.emit(metricBuilder.setMetric("hdfs/pull/size", size));
emitter.emit(metricBuilder.setMetric("hdfs/pull/duration", duration));
}
public InputStream getInputStream(Path path) throws IOException
{
return buildFileObject(path.toUri(), config).openInputStream();
}
@Override
public InputStream getInputStream(URI uri) throws IOException
{
if (!uri.getScheme().equalsIgnoreCase(HdfsStorageDruidModule.SCHEME)) {
throw new IAE("Don't know how to load SCHEME [%s] for URI [%s]", uri.getScheme(), uri.toString());
}
return buildFileObject(uri, config).openInputStream();
}
/**
* Return the "version" (aka last modified timestamp) of the URI
*
* @param uri The URI of interest
*
* @return The last modified timestamp of the uri in String format
*
* @throws IOException
*/
@Override
public String getVersion(URI uri) throws IOException
{
try {
return StringUtils.format("%d", buildFileObject(uri, config).getLastModified());View on GitHub (pinned to 9b90983fd2)
Solutions
- Verify druid.storage.type is hdfs on all nodes that must pull these segments and that segments were actually pushed to HDFS
- Check the loadSpec URI in the segment metadata in the metadata store; it must start with hdfs://
- Ensure the hdfs-storage extension is the only active storage provider, or that deep storage is not mixed between S3/local and HDFS
Example fix
// before (URI from wrong storage)
URI uri = new URI("s3://bucket/segment/index.zip");
puller.getInputStream(uri); // throws
// after
URI uri = new URI("hdfs://namenode/druid/segments/.../index.zip");
puller.getInputStream(uri); Defensive patterns
Strategy: validation
Validate before calling
if (!"hdfs".equalsIgnoreCase(uri.getScheme())) {
throw new IllegalArgumentException("Expected hdfs:// URI, got: " + uri);
}
puller.getInputStream(uri); Type guard
boolean isHdfsUri(java.net.URI uri) { return uri != null && "hdfs".equalsIgnoreCase(uri.getScheme()); } Try / catch
try {
in = puller.getInputStream(uri);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("Segment URI not on HDFS, check druid.storage.type/loadSpec: " + uri, e);
} Prevention
- Keep druid.storage.type consistent across all nodes
- Validate loadSpec URIs in the metadata store start with hdfs://
- Avoid mixing deep-storage extensions on one cluster
When it happens
Trigger: Calling getInputStream(uri) with a URI whose scheme is not 'hdfs' (case-insensitive check fails), e.g. an 's3://', 'file://', or local-path segment URI routed to the HDFS puller.
Common situations: Deep storage misconfiguration: druid.storage.type=hdfs is loaded but historical nodes still resolve segment URIs written by another storage type (S3, local); mixing storage extensions on the same cluster; hand-written load specs pointing at the wrong scheme.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- Unable to kill segment
- No files found at [%s]
- Argument [%s] is not a valid URI
- Segment path [%s] does not exist
- [%s] is a child directory, skipping
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/7915854c917929bd.
Report an issue: GitHub.