apache/druid · error · IllegalArgumentException

The %s property cannot be provided when the %s property is s

Error message

The %s property cannot be provided when the %s property is set

What it means

When an S3 catalog table uses the bucket property, object-level filtering via objectGlob is not allowed because the bucket style maps the whole bucket to a synthetic URI and glob filtering is applied differently. Druid throws this IllegalArgumentException if objectGlob appears in the inputSourceMap together with the bucket property. Use prefixes/uris style if glob filtering is needed.

Source

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

    final String bucket = table.resolvedTable().stringProperty(BUCKET_PROPERTY);
    final boolean hasBucket = bucket != null;
    final Map<String, Object> sourceMap = table.inputSourceMap;
    final boolean hasUris = sourceMap.containsKey(URIS_FIELD);
    final boolean hasPrefix = sourceMap.containsKey(PREFIXES_FIELD);
    final boolean hasObjects = sourceMap.containsKey(OBJECTS_FIELD);
    final boolean hasGlob = sourceMap.containsKey(OBJECT_GLOB_FIELD);
    if (hasBucket) {
      if (hasUris || hasPrefix || hasObjects) {
        throw new IAE(
            "Provide either the %s property, or one of the S3 input source fields %s, %s or %s, but not both.",
            BUCKET_PROPERTY,
            URIS_FIELD,
            PREFIXES_FIELD,
            OBJECTS_FIELD
        );
      }
      if (hasGlob) {
        throw new IAE(
            "The %s property cannot be provided when the %s property is set",
            OBJECT_GLOB_FIELD,
            BUCKET_PROPERTY
        );
      }

      // Patch in a dummy URI so that validation of the rest of the fields
      // will pass.
      sourceMap.put(URIS_FIELD, Collections.singletonList(bucket));
    }
    super.validate(table);
  }

  @Override
  protected List<ParameterDefn> adHocTableFnParameters()
  {
    return CatalogUtils.concatLists(
        Arrays.asList(

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Remove objectGlob from the inputSourceMap and rely on the bucket (or add prefixes instead of bucket to enable glob)
  2. Drop the bucket property and use uris/prefixes with objectGlob for filtered reads
  3. Broaden the bucket path so glob filtering is unnecessary

Example fix

// before
{"bucket": "my-bucket", "inputSource": {"type": "s3", "objectGlob": "**/*.json"}}
// after
{"inputSource": {"type": "s3", "prefixes": ["s3://my-bucket/data/"], "objectGlob": "**/*.json"}}
Defensive patterns

Strategy: validation

Validate before calling

if (spec.stringProperty("bucket") != null && spec.inputSourceMap.containsKey("objectGlob")) {
  throw new IllegalArgumentException("objectGlob cannot be used with the bucket property");
}

Type guard

boolean globAllowedWithBucket(String bucket, Map<String, Object> src) {
  return bucket == null || !src.containsKey("objectGlob");
}

Try / catch

try {
  tableDefn.validate(table);
} catch (IllegalArgumentException e) {
  // remove objectGlob or switch to prefixes-style addressing
}

Prevention

When it happens

Trigger: Calling validate() on a ResolvedExternalTable where the bucket property is set and the inputSourceMap also contains the objectGlob key.

Common situations: Users copying objectGlob from a raw S3InputSource config while also filling in the catalog bucket property; trying to restrict ingestion to *.json files while using the simpler bucket-based spec.

Related errors


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