apache/druid · error · IllegalArgumentException

S3 requires one of %s, %s or %s

Error message

S3 requires one of %s, %s or %s

What it means

This IllegalArgumentException comes from the S3 external table definition in Druid's catalog when converting table-function arguments into an S3 input source map. An S3 input source needs at least one way to locate objects: URIs (paths), prefixes, or a bucket with paths. The library throws this when the caller provided none of them, because the resulting input source would have no data locations at all.

Source

Thrown at extensions-core/s3-extensions/src/main/java/org/apache/druid/catalog/model/table/S3InputSourceDefn.java:222

    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) {
      jsonMap.put(PREFIXES_FIELD, prefixes);
    }
    if (hasBucket) {
      if (!hasPaths) {
        throw new IAE("When using the %s parameter, %s must also be provided", BUCKET_PARAMETER, PATHS_PARAMETER);
      }
      List<CloudObjectLocation> objects = new ArrayList<>();
      for (String obj : paths) {

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Add at least one location parameter to the table function call: 'paths' (list of S3 URIs), 'prefixes' (list of prefixes), or 'bucket' together with 'paths'.
  2. If using a bucket, also pass the 'paths' parameter listing object keys in that bucket.
  3. Verify parameter names match the catalog definition exactly (uri/uris/paths vs prefixes vs bucket).
  4. If the intent was to use a fully catalog-defined table, ensure the catalog input source itself defines URIs/prefixes and remove the expectation that the function supplies them.

Example fix

// before
SELECT * FROM TABLE(EXTERN('s3-ext' => ARRAY[]))
// after
SELECT * FROM TABLE(EXTERN(
  's3-ext' => ARRAY['s3://my-bucket/data/file.json']
))
Defensive patterns

Strategy: validation

Validate before calling

boolean hasUris = args != null && !args.getOrDefault("uris", List.of()).isEmpty();
boolean hasPaths = args != null && !args.getOrDefault("paths", List.of()).isEmpty();
boolean hasPrefixes = args != null && !args.getOrDefault("prefixes", List.of()).isEmpty();
boolean hasBucket = args != null && args.get("bucket") != null;
if (!hasUris && !hasPrefixes && !(hasBucket && hasPaths)) {
  throw new IllegalArgumentException("S3 external table requires one of: uris/paths, prefixes, or bucket + paths");
}

Prevention

When it happens

Trigger: Calling the S3 external table function (e.g. EXTERN with TABLE functions) without supplying any of the 'paths', 'bucket', or 'prefixes' parameters, or supplying only properties that do not map to one of these three parameters so all three boolean checks (hasUris, hasPrefixes, hasBucket) are false.

Common situations: Writing SQL EXTERN queries against an S3 catalog table and forgetting to pass the table function parameters; passing only credentials/endpoint properties; renaming or misspelling parameter names so the values never bind; building arguments programmatically with an empty map.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/5efc7b8bdfefcfd6. Report an issue: GitHub.