apache/druid · error · IAE
'%s' must be a string or an array of strings
Error message
'%s' must be a string or an array of strings
What it means
HdfsInputSource coerces its 'paths' property into a list of strings. If the provided value is neither a single string nor a list of strings (e.g. a number, object, or list containing non-strings), this IllegalArgumentException is thrown with the property name. It is input-validation for the HDFS input source spec.
Source
Thrown at extensions-core/hdfs-storage/src/main/java/org/apache/druid/inputsource/hdfs/HdfsInputSource.java:125
this.inputPaths.forEach(p -> verifyProtocol(configuration, inputSourceConfig, p));
}
@JsonIgnore
@Nonnull
@Override
public Set<String> getTypes()
{
return Collections.singleton(TYPE_KEY);
}
public static List<String> coerceInputPathsToList(Object inputPaths, String propertyName)
{
if (inputPaths instanceof String) {
return Collections.singletonList((String) inputPaths);
} else if (inputPaths instanceof List && ((List<?>) inputPaths).stream().allMatch(x -> x instanceof String)) {
return ((List<?>) inputPaths).stream().map(x -> (String) x).collect(Collectors.toList());
} else {
throw new IAE("'%s' must be a string or an array of strings", propertyName);
}
}
public static void verifyProtocol(Configuration conf, HdfsInputSourceConfig config, String pathString)
{
Path path = new Path(pathString);
try {
throwIfInvalidProtocol(config, path.getFileSystem(conf).getScheme());
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
private static void throwIfInvalidProtocol(HdfsInputSourceConfig config, String scheme)
{
if (!config.getAllowedProtocols().contains(StringUtils.toLowerCase(scheme))) {
throw new IAE("Only %s protocols are allowed", config.getAllowedProtocols());View on GitHub (pinned to 9b90983fd2)
Solutions
- Make 'paths' a JSON string or an array of strings, e.g. "paths": "hdfs://nn/data" or "paths": ["hdfs://nn/a", "hdfs://nn/b"].
- If you have many comma-separated paths, split them into a JSON array yourself; the source does not split strings.
- Validate the spec with the /druid/indexer/v1/task endpoint's validation or a JSON schema check before submitting.
- Quote numeric-looking path components as strings in JSON.
Example fix
// before
"inputSource": {"type": "hdfs", "paths": 123}
// after
"inputSource": {"type": "hdfs", "paths": ["hdfs://namenode:8020/druid/segments/"]} Defensive patterns
Strategy: validation
Validate before calling
static boolean validHdfsPaths(Object paths) {
return paths instanceof String
|| (paths instanceof List && ((List<?>) paths).stream().allMatch(x -> x instanceof String));
} Type guard
static List<String> asPathList(Object v) {
if (v instanceof String) return Collections.singletonList((String) v);
if (v instanceof List && ((List<?>) v).stream().allMatch(String.class::isInstance)) {
return ((List<?>) v).stream().map(String.class::cast).collect(Collectors.toList());
}
return null; // invalid
} Try / catch
try { source = mapper.readValue(spec, InputSource.class); }
catch (IllegalArgumentException e) {
log.error("Bad hdfs inputSource paths: %s", e.getMessage());
} Prevention
- Keep 'paths' as a JSON string or array of strings in specs.
- Validate ingestion specs (schema/endpoint) before submission.
- Never let templating tools emit numbers/objects into 'paths'.
- Split comma-separated paths into array elements yourself.
When it happens
Trigger: Submitting an ingestion spec whose hdfs inputSource 'paths' is a non-string (e.g. numeric path, JSON object), or an array containing nulls/numbers/objects.
Common situations: Hand-edited ingestion specs; templating tools inserting non-string values; users passing a comma-joined list as an object or nesting paths incorrectly.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Only %s protocols are allowed
- S3 requires one of %s, %s or %s
- When using the %s parameter, %s must also be provided
- Specify exactly one of 'interval' and 'segments'
- At least one of baseDir or files should be specified
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/dd87dc3a3df4ca73.
Report an issue: GitHub.