apache/druid · error · IllegalStateException
Error! More than one matching entry[%d] found for [%s]?!
Error message
Error! More than one matching entry[%d] found for [%s]?!
What it means
SQLMetadataConnector.lookupWithHandle() fetches rows matching a single key and expects at most one result. When the query returns more than one matching entry it throws IllegalStateException, signaling that the uniqueness assumption backing the lookup table (e.g. config/lookup tables keyed by name) has been violated.
Source
Thrown at server/src/main/java/org/apache/druid/metadata/SQLMetadataConnector.java:915
final String key
)
{
final String selectStatement = StringUtils.format(
"SELECT %s FROM %s WHERE %s = :key", valueColumn,
tableName, keyColumn
);
List<byte[]> matched = handle.createQuery(selectStatement)
.bind("key", key)
.map(ByteArrayMapper.FIRST)
.list();
if (matched.isEmpty()) {
return null;
}
if (matched.size() > 1) {
throw new ISE("Error! More than one matching entry[%d] found for [%s]?!", matched.size(), key);
}
return matched.get(0);
}
public MetadataStorageConnectorConfig getConfig()
{
return config.get();
}
protected static BasicDataSource makeDatasource(
MetadataStorageConnectorConfig connectorConfig,
String validationQuery
)
{
BasicDataSource dataSource;
try {View on GitHub (pinned to 9b90983fd2)
Solutions
- Query the backing table for the duplicated key and delete the extra rows, keeping the correct one.
- Re-apply the schema so the key column has a UNIQUE constraint to prevent recurrence.
- Identify the writer that bypassed uniqueness (manual SQL or buggy tooling) and fix it.
Example fix
// before String value = connector.lookup(tableName, "name", key, "payload"); // after // dedupe first // DELETE FROM tableName WHERE name = :key AND rowid NOT IN (SELECT MIN(rowid) FROM tableName WHERE name = :key); String value = connector.lookup(tableName, "name", key, "payload");
Defensive patterns
Strategy: validation
Validate before calling
int count = dbi.withHandle(h ->
h.createQuery("SELECT COUNT(*) FROM " + tableName + " WHERE " + keyColumn + " = :k")
.bind("k", key).mapTo(Integer.class).findOnly());
if (count > 1) { /* dedupe before lookup */ } Try / catch
try {
String value = connector.lookup(tableName, keyColumn, key, valueColumn);
} catch (IllegalStateException e) {
log.error(e, "Duplicate rows for key %s — dedupe table", key);
} Prevention
- Enforce UNIQUE constraints on lookup-table key columns
- Never modify metadata tables with raw SQL outside Druid's APIs
- Reconcile metadata tables after crashed writes or restores
When it happens
Trigger: Calling lookup (via lookupWithHandle) against a table whose uniqueness constraint is missing or bypassed, so multiple rows exist for the same key.
Common situations: Direct DB manipulation inserting duplicates; metadata store created without unique indexes; failed/crashed writes leaving two versions of the same key.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Failed to insert upgrade segments in DB: %s
- Couldn't generate AWS token.
- Tried to insert a duplicate table: %s
- Failed to fetch google cloud storage object from bucket [%s]
- Expected instance of %s, got %s
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/6e46d0162731d690.
Report an issue: GitHub.