apache/druid · error · IllegalArgumentException
URI[ ] has invalid scheme[ ]
Error message
URI[%s] has invalid scheme[%s]
What it means
ServiceLocation.fromUri converts a URI into a service location, but only http and https schemes are supported. Any other scheme (e.g. ws, ftp, or a missing scheme) causes this IllegalArgumentException. It exists to fail fast on URIs that cannot map to an HTTP service endpoint.
Solutions
- Prefix the URI string with "http://" (or "https://") in the configuration or code that builds it.
- Check the scheme before calling fromUri and normalize known aliases to http/https.
- Verify the config property feeding the URI (e.g. druid.discovery URLs) is a full absolute URL.
Example fix
// before
ServiceLocation loc = ServiceLocation.fromUri(new URI("mybroker:8082"), basePath);
// after
ServiceLocation loc = ServiceLocation.fromUri(new URI("http://mybroker:8082"), basePath); Defensive patterns
Strategy: validation
Validate before calling
String s = uri.toString();
if (!s.startsWith("http://") && !s.startsWith("https://")) {
throw new IllegalArgumentException("Service URI must use http/https: " + s);
} Prevention
- Always store fully-qualified http(s) URLs in configuration, never bare host:port.
- Normalize scheme aliases in one helper before constructing URIs.
When it happens
Trigger: Calling ServiceLocation.fromUri with a URI whose scheme is not exactly "http" or "https" — e.g. fromUri(new URI("ftp://host:8020")) or a URI built from a config string lacking a scheme.
Common situations: Misconfigured service URLs in Druid properties (forgot http:// prefix), copy-pasted internal scheme names (https vs websockets), or programmatically constructed URIs with relative paths that resolve to a null scheme.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 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/bef895bfb3786ef4.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/main/java/org/apache/druid/rpc/ServiceLocation.java:119
}
}
if (uri.getRawQuery() != null) {
basePath.append('?').append(uri.getRawQuery());
}
if (uri.getRawFragment() != null) {
basePath.append('#').append(uri.getRawFragment());
}
if (HTTP_SCHEME.equals(scheme)) {
final int port = uri.getPort() < 0 ? HTTP_DEFAULT_PORT : uri.getPort();
return new ServiceLocation(host, port, -1, basePath.toString());
} else if (HTTPS_SCHEME.equals(scheme)) {
final int port = uri.getPort() < 0 ? HTTPS_DEFAULT_PORT : uri.getPort();
return new ServiceLocation(host, -1, port, basePath.toString());
} else {
throw new IAE("URI[%s] has invalid scheme[%s]", uri, scheme);
}
}
/**
* Create a service location based on a {@link DruidServerMetadata}.
*
* @throws IllegalArgumentException if the server metadata cannot be mapped to a service location.
*/
public static ServiceLocation fromDruidServerMetadata(final DruidServerMetadata druidServerMetadata)
{
final String host = getHostFromString(
Preconditions.checkNotNull(
druidServerMetadata.getHost(),
"Host was null for druid server metadata[%s]",
druidServerMetadata
)
);
int plaintextPort = getPortFromString(druidServerMetadata.getHostAndPort());View on GitHub (pinned to 9b90983fd2)