apache/druid · error · IllegalArgumentException
given update for lookup
Error message
given update for lookup [%s]:[%s] can't replace existing spec [%s].
What it means
When updating lookups in an existing tier, each new lookup spec must semantically replace the currently stored spec. LookupExtractorFactoryMapContainer.replaces() enforces monotonic versioning; if the submitted spec cannot replace the existing one (e.g. an equal or older version), updateLookups throws this IllegalArgumentException naming the tier, lookup key, and existing spec.
Solutions
- Bump the 'version' field in the lookup spec to a value greater than the existing spec and re-POST.
- If the change is unintentional, skip re-posting an identical spec.
- Delete the lookup first (DELETE endpoint) if you truly need to reset it, then create it anew.
Example fix
// before
{"dataSource": "x", "version": "2023-01-01T00:00:00.000Z", ...}
// after
{"dataSource": "x", "version": "2024-06-01T00:00:00.000Z", ...} Defensive patterns
Strategy: validation
Validate before calling
function isNewerVersion(newSpec, existingSpec) {
return String(newSpec.version) > String(existingSpec.version);
}
if (!isNewerVersion(incoming, existing)) {
throw new Error(`bump version: incoming ${incoming.version} <= existing ${existing.version}`);
} Type guard
function canReplace(incoming, existing) {
return incoming && existing && new Date(incoming.version) > new Date(existing.version);
} Try / catch
try {
await updateLookups(tier, lookupName, spec);
} catch (IAE e) {
if (e.getMessage().contains("can't replace existing spec")) {
log.warn(`Skipping stale update for ${lookupName}; bump the version field`);
} else { throw e; }
} Prevention
- Always bump the 'version' field (timestamp-style string) whenever editing a lookup spec.
- Make automation idempotent: skip re-posting when the spec is unchanged.
- Fetch the current spec first and compare versions before submitting an update.
When it happens
Trigger: POSTing an update for lookup tier:lookupName whose spec has the same or lower 'version' field than the existing spec, or is otherwise judged non-replacing by the container's replaces() comparison.
Common situations: Re-running an automation script that re-posts the same spec with the same version; CI replaying stale config; editing a lookup without bumping its 'version' field.
Related errors
- Cluster-level rules cannot be empty.
- Limit must be greater than zero!
- Not initialized. If this is the first lookup, post an empty…
- A local input source accepts only one of
- A local input source can set parameter
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/2b611a8b99986bed.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/main/java/org/apache/druid/server/lookup/cache/LookupCoordinatorManager.java:233
updatedSpec = updateSpec;
} else {
// Needs update
updatedSpec = new HashMap<>(priorSpec);
for (final Map.Entry<String, Map<String, LookupExtractorFactoryMapContainer>> tierEntry : updateSpec.entrySet()) {
final String tier = tierEntry.getKey();
final Map<String, LookupExtractorFactoryMapContainer> updateTierSpec = tierEntry.getValue();
final Map<String, LookupExtractorFactoryMapContainer> priorTierSpec = priorSpec.get(tier);
if (priorTierSpec == null) {
// New tier
updatedSpec.put(tier, updateTierSpec);
} else {
// Update existing tier
final Map<String, LookupExtractorFactoryMapContainer> updatedTierSpec = new HashMap<>(priorTierSpec);
for (Map.Entry<String, LookupExtractorFactoryMapContainer> e : updateTierSpec.entrySet()) {
if (updatedTierSpec.containsKey(e.getKey()) && !e.getValue().replaces(updatedTierSpec.get(e.getKey()))) {
throw new IAE(
"given update for lookup [%s]:[%s] can't replace existing spec [%s].",
tier,
e.getKey(),
updatedTierSpec.get(e.getKey())
);
}
}
updatedTierSpec.putAll(updateTierSpec);
updatedSpec.put(tier, updatedTierSpec);
}
}
}
return configManager.set(LOOKUP_CONFIG_KEY, updatedSpec, auditInfo).isOk();
}
}
public Map<String, Map<String, LookupExtractorFactoryMapContainer>> getKnownLookups()
{View on GitHub (pinned to 9b90983fd2)