{"record":{"id":"caa6ffe980cf3a78","repo":"apache/druid","slug":"only-s-protocols-are-allowed-caa6ff","errorCode":null,"errorMessage":"Only %s protocols are allowed","messagePattern":"Only (.+?) protocols are allowed","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/data/input/impl/HttpInputSource.java","lineNumber":96,"sourceCode":"      @JacksonInject HttpInputSourceConfig config\n  )\n  {\n    Preconditions.checkArgument(uris != null && !uris.isEmpty(), \"Empty URIs\");\n    throwIfInvalidProtocols(config, uris);\n    this.uris = uris;\n    this.httpAuthenticationUsername = httpAuthenticationUsername;\n    this.httpAuthenticationPasswordProvider = httpAuthenticationPasswordProvider;\n    this.systemFields = systemFields == null ? SystemFields.none() : systemFields;\n    this.requestHeaders = requestHeaders == null ? Collections.emptyMap() : requestHeaders;\n    throwIfForbiddenHeaders(config, this.requestHeaders);\n    this.config = config;\n  }\n\n  public static void throwIfInvalidProtocols(HttpInputSourceConfig config, List<URI> uris)\n  {\n    for (URI uri : uris) {\n      if (!config.getAllowedProtocols().contains(StringUtils.toLowerCase(uri.getScheme()))) {\n        throw new IAE(\"Only %s protocols are allowed\", config.getAllowedProtocols());\n      }\n    }\n  }\n\n  public static void throwIfForbiddenHeaders(HttpInputSourceConfig config, Map<String, String> requestHeaders)\n  {\n    for (Map.Entry<String, String> entry : requestHeaders.entrySet()) {\n      if (!config.getAllowedHeaders().contains(StringUtils.toLowerCase(entry.getKey()))) {\n        throw InvalidInput.exception(\"Got forbidden header [%s], allowed headers are only [%s]. You can control the allowed headers by updating druid.ingestion.http.allowedHeaders\",\n                                     entry.getKey(), config.getAllowedHeaders()\n        );\n      }\n    }\n  }\n\n  @JsonIgnore\n  @Nonnull\n  @Override","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/data/input/impl/HttpInputSource.java#L78-L114","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","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"],"exampleFix":"// before\n\"inputSource\": {\"type\":\"http\",\"uris\":[\"s3://bucket/data.json\"]}\n// after\n\"inputSource\": {\"type\":\"http\",\"uris\":[\"https://example.com/data.json\"]}\n// or allow the scheme: -Ddruid.input.http.allowedProtocols=[\"https\",\"s3\"]","handlingStrategy":"validation","validationCode":"// Before creating the input source\nList<String> allowed = getAllowedProtocols(); // from druid.input.http.allowedProtocols\nfor (URI u : uris) {\n    if (!allowed.contains(u.getScheme().toLowerCase(Locale.ROOT))) {\n        throw new IllegalArgumentException(\"Scheme not allowed: \" + u);\n    }\n}","typeGuard":null,"tryCatchPattern":"try { new HttpInputSource(uris, headers, systemFields, config); } catch (IAE e) { /* rewrite URIs to https or pick a matching input source type */ }","preventionTips":["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"],"tags":["http","security","configuration","uri"],"backgroundTag":"invalid-url","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"}