{"record":{"id":"b6f06bff081f511c","repo":"apache/druid","slug":"only-s-protocols-are-allowed","errorCode":null,"errorMessage":"Only %s protocols are allowed","messagePattern":"Only (.+?) protocols are allowed","errorType":"validation","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"extensions-core/hdfs-storage/src/main/java/org/apache/druid/inputsource/hdfs/HdfsInputSource.java","lineNumber":143,"sourceCode":"      throw new IAE(\"'%s' must be a string or an array of strings\", propertyName);\n    }\n  }\n\n  public static void verifyProtocol(Configuration conf, HdfsInputSourceConfig config, String pathString)\n  {\n    Path path = new Path(pathString);\n    try {\n      throwIfInvalidProtocol(config, path.getFileSystem(conf).getScheme());\n    }\n    catch (IOException e) {\n      throw new RuntimeException(e);\n    }\n  }\n\n  private static void throwIfInvalidProtocol(HdfsInputSourceConfig config, String scheme)\n  {\n    if (!config.getAllowedProtocols().contains(StringUtils.toLowerCase(scheme))) {\n      throw new IAE(\"Only %s protocols are allowed\", config.getAllowedProtocols());\n    }\n  }\n\n  /**\n   * Matches Hadoop's FileInputFormat hidden-file filter: rejects paths whose name starts with '_' or '.'.\n   */\n  private static boolean isHiddenPath(Path path)\n  {\n    final String name = path.getName();\n    return name.startsWith(\"_\") || name.startsWith(\".\");\n  }\n\n  public static Collection<Path> getPaths(List<String> inputPaths, Configuration configuration) throws IOException\n  {\n    if (inputPaths.isEmpty()) {\n      return Collections.emptySet();\n    }\n","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/hdfs-storage/src/main/java/org/apache/druid/inputsource/hdfs/HdfsInputSource.java#L125-L161","documentation":"HdfsInputSource restricts path schemes to an allowlist (allAllowedProtocols from HdfsInputSourceConfig, defaulting to a fixed set such as hdfs/file). throwIfInvalidProtocol rejects any path whose scheme is not in that list with this IllegalArgumentException listing the allowed protocols.","triggerScenarios":"Ingesting via hdfs inputSource with a path using s3a://, gs://, http://, or another scheme not present in druid.inputsource.hdfs.allowedProtocols; also triggered when config explicitly narrows the allowlist and existing paths no longer qualify.","commonSituations":"Copying specs between clusters where one allows s3a and the other does not; security hardening that trimmed allowedProtocols; users mistakenly using the hdfs source for cloud object stores instead of the s3/gcs input sources.","solutions":["Use a scheme-appropriate path (hdfs://...) or switch to the dedicated s3/gs/azure input source for cloud storage.","Add the needed scheme to config: druid.inputsource.hdfs.allowedProtocols=[\"hdfs\",\"file\",\"s3a\"] (comma-separated runtime property).","Check the exact allowed list in the error message and align your paths with it.","If protocols were intentionally restricted, request a config change from the cluster operator rather than bypassing it."],"exampleFix":"// before\n\"paths\": [\"s3a://bucket/data\"]   // hdfs input source\n// after\n\"inputSource\": {\"type\": \"s3\", \"uris\": [\"s3://bucket/data\"]}\n// or on the hdfs source:\n// druid.inputsource.hdfs.allowedProtocols=hdfs,file,s3a","handlingStrategy":"validation","validationCode":"static boolean protocolAllowed(String path, Set<String> allowed) {\n  String scheme = path.contains(\"://\") ? path.substring(0, path.indexOf(\"://\")) : \"\";\n  return allowed.contains(scheme.toLowerCase(Locale.ROOT));\n}","typeGuard":null,"tryCatchPattern":"try { verifyProtocol(conf, config, pathString); }\ncatch (IAE e) { log.error(\"Path scheme rejected; allowed: %s\", config.getAllowedProtocols()); }","preventionTips":["Match path schemes to druid.inputsource.hdfs.allowedProtocols before submitting tasks.","Use dedicated s3/gcs input sources for cloud object stores.","After protocol config changes, audit existing specs for now-disallowed schemes.","Keep schemes lowercase; comparison is case-insensitive but paths should be canonical."],"tags":["hdfs","input-source","security","protocol"],"backgroundTag":"invalid-enum-value","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"}