apache/druid · error · IllegalArgumentException
S3 accepts only one of %s, %s or %s
Error message
S3 accepts only one of %s, %s or %s
What it means
The S3 table function accepts exactly one primary location selector among paths (with bucket), bucket, and prefixes; uris may only appear alone. Druid throws this IllegalArgumentException when more than one of uris, prefixes, or bucket is supplied, since combining them is ambiguous. Each parameter describes a different way of enumerating S3 objects and they cannot be merged.
Source
Thrown at extensions-core/s3-extensions/src/main/java/org/apache/druid/catalog/model/table/S3InputSourceDefn.java:214
jsonMap.put(InputSource.TYPE_PROPERTY, S3StorageDruidModule.SCHEME);
final List<String> uris = CatalogUtils.getStringArray(args, URIS_PARAMETER);
final List<String> prefixes = CatalogUtils.getStringArray(args, PREFIXES_PARAMETER);
final String bucket = CatalogUtils.getNonBlankString(args, BUCKET_PARAMETER);
final List<String> paths = CatalogUtils.getStringArray(args, PATHS_PARAMETER);
final String objectGlob = CatalogUtils.getNonBlankString(args, OBJECT_GLOB_PARAMETER);
final boolean hasUris = uris != null;
final boolean hasPrefixes = prefixes != null;
final boolean hasBucket = bucket != null;
final boolean hasPaths = !CollectionUtils.isNullOrEmpty(paths);
if (hasPaths && !hasBucket) {
throw new IAE(
"S3 requires the %s parameter if %s is set",
BUCKET_PARAMETER,
PATHS_PARAMETER
);
}
if ((hasUris && (hasPrefixes || hasBucket)) || (hasPrefixes && hasBucket)) {
throw new IAE(
"S3 accepts only one of %s, %s or %s",
PATHS_PARAMETER,
BUCKET_PARAMETER,
PREFIXES_PARAMETER
);
}
if (!hasUris && !hasPrefixes && !hasBucket) {
throw new IAE(
"S3 requires one of %s, %s or %s",
PATHS_PARAMETER,
BUCKET_PARAMETER,
PREFIXES_PARAMETER
);
}
if (hasUris) {
jsonMap.put(URIS_FIELD, CatalogUtils.stringListToUriList(uris));
}
if (hasPrefixes) {View on GitHub (pinned to 9b90983fd2)
Solutions
- Keep only one of uris, prefixes, or bucket (plus paths if bucket is used)
- If both a bucket and specific objects are desired, express them as full s3:// uris in the uris parameter
- Use prefixes alone, encoding the bucket inside each prefix URI
Example fix
// before EXTERNAL(... uris => ARRAY['s3://b/a.json'], bucket => 'b', ...) // after EXTERNAL(... uris => ARRAY['s3://b/a.json'], ...)
Defensive patterns
Strategy: validation
Validate before calling
int selectors = (uris != null ? 1 : 0) + (prefixes != null ? 1 : 0) + (bucket != null ? 1 : 0);
if (selectors > 1) {
throw new IllegalArgumentException("Provide only one of uris, prefixes, or bucket");
} Try / catch
try {
runExternalQuery(args);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("accepts only one of")) { /* keep one selector and retry */ }
} Prevention
- Build the SQL from one canonical location parameter in application code
- Never append all S3 location parameters from a config map; select one explicitly
- Convert bucket+object combinations into full s3:// uris before calling the function
When it happens
Trigger: Calling the S3 EXTERNAL table function with any two of uris, prefixes, or bucket set simultaneously (e.g. uris plus bucket, or prefixes plus bucket).
Common situations: Adding a bucket parameter to a working uris-based call thinking it narrows the search; script-generated SQL that appends all location parameters; combining prefixes with bucket to try to 'scope' prefixes.
Understand the failure class
Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.
Related errors
- S3 requires the %s parameter if %s is set
- Provide either the %s property, or one of the S3 input sourc
- The %s property cannot be provided when the %s property is s
- Function requires a schema: TABLE(%s(...)) (<col> <type>...)
- Cannot translate sqlTypeName[%s] to Druid type for field[%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/f13d1413c782ce65.
Report an issue: GitHub.