apache/druid · error · IllegalArgumentException
Either uri xor uriPrefix required
Error message
Either uri xor uriPrefix required
What it means
UriExtractionNamespace's constructor requires exactly one of `uri` (a single file URI) or `uriPrefix` (a URI prefix for multi-file loading) — the two are mutually exclusive and one is mandatory. When both are set, or neither is set, it throws this IAE during namespace config deserialization.
Source
Thrown at extensions-core/lookups-cached-global/src/main/java/org/apache/druid/query/lookup/namespace/UriExtractionNamespace.java:107
@JsonProperty(value = "uriPrefix", required = false)
URI uriPrefix,
@JsonProperty(value = "fileRegex", required = false)
String fileRegex,
@JsonProperty(value = "namespaceParseSpec", required = true)
FlatDataParser namespaceParseSpec,
@Min(0) @JsonProperty(value = "pollPeriod", required = false) @Nullable
Period pollPeriod,
@Deprecated
@JsonProperty(value = "versionRegex", required = false)
String versionRegex,
@JsonProperty(value = "maxHeapPercentage") @Nullable
Long maxHeapPercentage
)
{
this.uri = uri;
this.uriPrefix = uriPrefix;
if ((uri != null) == (uriPrefix != null)) {
throw new IAE("Either uri xor uriPrefix required");
}
this.namespaceParseSpec = Preconditions.checkNotNull(namespaceParseSpec, "namespaceParseSpec");
if (pollPeriod == null) {
// Warning because if UriExtractionNamespace is being used for lookups, any updates to the database will not
// be picked up after the node starts. So for use casses where nodes start at different times (like streaming
// ingestion with peons) there can be data inconsistencies across the cluster.
LOG.warn("No pollPeriod configured for UriExtractionNamespace - entries will be loaded only once at startup");
this.pollPeriod = Period.ZERO;
} else {
this.pollPeriod = pollPeriod;
}
this.fileRegex = fileRegex == null ? versionRegex : fileRegex;
if (fileRegex != null && versionRegex != null) {
throw new IAE("Cannot specify both versionRegex and fileRegex. versionRegex is deprecated");
}
if (uri != null && this.fileRegex != null) {
throw new IAE("Cannot define both uri and fileRegex");View on GitHub (pinned to 9b90983fd2)
Solutions
- Remove either the `uri` or the `uriPrefix` field so exactly one remains.
- If the config should point at a single file, keep `uri` and delete `uriPrefix`; for a directory/prefix of files, keep `uriPrefix` and delete `uri`.
- Check for typo'd keys that silently leave both fields null.
- Validate the lookup JSON before POSTing it to the lookup coordinator.
Example fix
// before
{"type":"uri", "uri":"s3://bucket/f.csv", "uriPrefix":"s3://bucket/"}
// after
{"type":"uri", "uriPrefix":"s3://bucket/"} Defensive patterns
Strategy: validation
Validate before calling
// java
boolean hasUri = cfg.has("uri") && !cfg.get("uri").isNull();
boolean hasPrefix = cfg.has("uriPrefix") && !cfg.get("uriPrefix").isNull();
if (hasUri == hasPrefix) throw new IllegalArgumentException("exactly one of uri/uriPrefix required"); Try / catch
// java
try { mapper.readValue(json, UriExtractionNamespace.class); }
catch (IllegalArgumentException e) {
if (e.getMessage().contains("Either uri xor uriPrefix")) { /* fix config */ }
} Prevention
- Keep exactly one of uri/uriPrefix in lookup JSON.
- Validate lookup configs against a JSON schema before posting.
- When migrating between single-file and prefix setups, delete the other field.
When it happens
Trigger: Constructing UriExtractionNamespace (or submitting lookup JSON) with both uri and uriPrefix set, or with both null/absent; Jackson binding a lookup config missing the uri field.
Common situations: Copy-pasted lookup JSON where an old `uri` field was left in place after adding `uriPrefix`; typos in field names (e.g. "url" instead of "uri") leaving both effectively null; migrated configs with leftover fields.
Related errors
- Cannot define both uri and fileRegex
- Cannot specify both versionRegex and fileRegex. versionRegex
- Could not parse `fileRegex` [%s]
- Set only one of 'key' or 'sharedAccessStorageToken' or 'useA
- Invalid pod adapter [%s], only pod adapter [%s] can be speci
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/91f2e6c33d40e980.
Report an issue: GitHub.