apache/druid · error · IllegalArgumentException
Only %s protocols are allowed
Error message
Only %s protocols are allowed
What it means
HttpInputSource.throwIfInvalidProtocols validates every URI against druid.input.http.allowedProtocols (default http and https). Any URI whose scheme is not on the allowlist is rejected with IAE before any fetch is attempted, protecting against SSRF to file/ftp/other schemes.
Source
Thrown at processing/src/main/java/org/apache/druid/data/input/impl/HttpInputSource.java:96
@JacksonInject HttpInputSourceConfig config
)
{
Preconditions.checkArgument(uris != null && !uris.isEmpty(), "Empty URIs");
throwIfInvalidProtocols(config, uris);
this.uris = uris;
this.httpAuthenticationUsername = httpAuthenticationUsername;
this.httpAuthenticationPasswordProvider = httpAuthenticationPasswordProvider;
this.systemFields = systemFields == null ? SystemFields.none() : systemFields;
this.requestHeaders = requestHeaders == null ? Collections.emptyMap() : requestHeaders;
throwIfForbiddenHeaders(config, this.requestHeaders);
this.config = config;
}
public static void throwIfInvalidProtocols(HttpInputSourceConfig config, List<URI> uris)
{
for (URI uri : uris) {
if (!config.getAllowedProtocols().contains(StringUtils.toLowerCase(uri.getScheme()))) {
throw new IAE("Only %s protocols are allowed", config.getAllowedProtocols());
}
}
}
public static void throwIfForbiddenHeaders(HttpInputSourceConfig config, Map<String, String> requestHeaders)
{
for (Map.Entry<String, String> entry : requestHeaders.entrySet()) {
if (!config.getAllowedHeaders().contains(StringUtils.toLowerCase(entry.getKey()))) {
throw InvalidInput.exception("Got forbidden header [%s], allowed headers are only [%s]. You can control the allowed headers by updating druid.ingestion.http.allowedHeaders",
entry.getKey(), config.getAllowedHeaders()
);
}
}
}
@JsonIgnore
@Nonnull
@OverrideView on GitHub (pinned to 9b90983fd2)
Solutions
- Change the URI to use an allowed scheme (http/https by default)
- Add the needed scheme to the 'druid.input.http.allowedProtocols' runtime property, e.g. -Ddruid.input.http.allowedProtocols=["http","https"]
- Use the input source type matching the scheme (S3InputSource, LocalInputSource) instead of HttpInputSource
Example fix
// before
"inputSource": {"type":"http","uris":["s3://bucket/data.json"]}
// after
"inputSource": {"type":"http","uris":["https://example.com/data.json"]}
// or allow the scheme: -Ddruid.input.http.allowedProtocols=["https","s3"] Defensive patterns
Strategy: validation
Validate before calling
// Before creating the input source
List<String> allowed = getAllowedProtocols(); // from druid.input.http.allowedProtocols
for (URI u : uris) {
if (!allowed.contains(u.getScheme().toLowerCase(Locale.ROOT))) {
throw new IllegalArgumentException("Scheme not allowed: " + u);
}
} Try / catch
try { new HttpInputSource(uris, headers, systemFields, config); } catch (IAE e) { /* rewrite URIs to https or pick a matching input source type */ } Prevention
- Align URI schemes with the cluster's allowedProtocols config when writing specs
- Use http/https URIs only with HttpInputSource; use S3InputSource/LocalInputSource for other schemes
- Remember scheme matching is lowercase — normalize URIs
When it happens
Trigger: Creating an HttpInputSource with a URI whose scheme (e.g. file, s3, ftp, or an uppercase variant blocked by config) is not present in HttpInputSourceConfig.getAllowedProtocols().
Common situations: Pasting an s3:// or file:// URI into an http input source; enterprise deployments that restrict allowedProtocols to https only while specs use http://; machine-generated specs carrying non-HTTP URIs.
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
- authResult.getErrorMessage()
- authResult.getErrorMessage()
- authResult.getErrorMessage()
- Property[%s] must be set
- Bad URL: %s
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/caa6ffe980cf3a78.
Report an issue: GitHub.