{"record":{"id":"6e46d0162731d690","repo":"apache/druid","slug":"error-more-than-one-matching-entry-d-found-for","errorCode":null,"errorMessage":"Error! More than one matching entry[%d] found for [%s]?!","messagePattern":"Error! More than one matching entry\\[(.+?)\\] found for \\[(.+?)\\]\\?!","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/metadata/SQLMetadataConnector.java","lineNumber":915,"sourceCode":"      final String key\n  )\n  {\n    final String selectStatement = StringUtils.format(\n        \"SELECT %s FROM %s WHERE %s = :key\", valueColumn,\n        tableName, keyColumn\n    );\n\n    List<byte[]> matched = handle.createQuery(selectStatement)\n                                 .bind(\"key\", key)\n                                 .map(ByteArrayMapper.FIRST)\n                                 .list();\n\n    if (matched.isEmpty()) {\n      return null;\n    }\n\n    if (matched.size() > 1) {\n      throw new ISE(\"Error! More than one matching entry[%d] found for [%s]?!\", matched.size(), key);\n    }\n\n    return matched.get(0);\n  }\n\n  public MetadataStorageConnectorConfig getConfig()\n  {\n    return config.get();\n  }\n\n  protected static BasicDataSource makeDatasource(\n      MetadataStorageConnectorConfig connectorConfig,\n      String validationQuery\n  )\n  {\n    BasicDataSource dataSource;\n\n    try {","sourceCodeStart":897,"sourceCodeEnd":933,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/metadata/SQLMetadataConnector.java#L897-L933","documentation":"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.","triggerScenarios":"Calling lookup (via lookupWithHandle) against a table whose uniqueness constraint is missing or bypassed, so multiple rows exist for the same key.","commonSituations":"Direct DB manipulation inserting duplicates; metadata store created without unique indexes; failed/crashed writes leaving two versions of the same key.","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."],"exampleFix":"// before\nString value = connector.lookup(tableName, \"name\", key, \"payload\");\n// after\n// dedupe first\n// DELETE FROM tableName WHERE name = :key AND rowid NOT IN (SELECT MIN(rowid) FROM tableName WHERE name = :key);\nString value = connector.lookup(tableName, \"name\", key, \"payload\");","handlingStrategy":"validation","validationCode":"int count = dbi.withHandle(h ->\n    h.createQuery(\"SELECT COUNT(*) FROM \" + tableName + \" WHERE \" + keyColumn + \" = :k\")\n     .bind(\"k\", key).mapTo(Integer.class).findOnly());\nif (count > 1) { /* dedupe before lookup */ }","typeGuard":null,"tryCatchPattern":"try {\n  String value = connector.lookup(tableName, keyColumn, key, valueColumn);\n} catch (IllegalStateException e) {\n  log.error(e, \"Duplicate rows for key %s — dedupe table\", key);\n}","preventionTips":["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"],"tags":["metadata","database","duplicate-key","invariant-violation"],"backgroundTag":"internal-invariant-violation","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}