{"record":{"id":"6245ba976bf43af0","repo":"apache/hadoop","slug":"keyversion-s-does-not-belong-to-the-key-s","errorCode":null,"errorMessage":"KeyVersion '%s' does not belong to the key '%s'","messagePattern":"KeyVersion '(.+?)' does not belong to the key '(.+?)'","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KeyAuthorizationKeyProvider.java","lineNumber":259,"sourceCode":"    try {\n      doAccessCheck(encryptionKeyName, KeyOpType.GENERATE_EEK);\n      return provider.generateEncryptedKey(encryptionKeyName);\n    } finally {\n      readLock.unlock();\n    }\n  }\n\n  private void verifyKeyVersionBelongsToKey(EncryptedKeyVersion ekv)\n      throws IOException {\n    String kn = ekv.getEncryptionKeyName();\n    String kvn = ekv.getEncryptionKeyVersionName();\n    KeyVersion kv = provider.getKeyVersion(kvn);\n    if (kv == null) {\n      throw new IllegalArgumentException(String.format(\n          \"'%s' not found\", kvn));\n    }\n    if (!kv.getName().equals(kn)) {\n      throw new IllegalArgumentException(String.format(\n          \"KeyVersion '%s' does not belong to the key '%s'\", kvn, kn));\n    }\n  }\n\n  @Override\n  public KeyVersion decryptEncryptedKey(EncryptedKeyVersion encryptedKeyVersion)\n          throws IOException, GeneralSecurityException {\n    readLock.lock();\n    try {\n      verifyKeyVersionBelongsToKey(encryptedKeyVersion);\n      doAccessCheck(\n          encryptedKeyVersion.getEncryptionKeyName(), KeyOpType.DECRYPT_EEK);\n      return provider.decryptEncryptedKey(encryptedKeyVersion);\n    } finally {\n      readLock.unlock();\n    }\n  }\n","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KeyAuthorizationKeyProvider.java#L241-L277","documentation":"The second check in verifyKeyVersionBelongsToKey (line 259): the referenced key version exists, but its key name does not equal the encryption key name carried in the EncryptedKeyVersion (the name field of the decrypt request). It throws IllegalArgumentException \"KeyVersion '<v>' does not belong to the key '<k>'\" (HTTP 400), catching client requests that mix a version name from one key with the name of another.","triggerScenarios":"POST /v1/keyversion/{versionName}/_eek?eek_op=decrypt where versionName belongs to key B but the JSON body's name field (and EDEK material) names key A — e.g. hand-assembled decrypt requests, or a client bug that pairs an EDEK with the wrong key name.","commonSituations":"Manual curl testing with mismatched name/version pairs; client code caching version names across keys; refactoring that swapped key name and version name fields; multi-key applications mixing up per-key EDEK state.","solutions":["Send the key name that actually owns the version: both values come from the same generateEncryptedKey response (EncryptedKeyVersion.getEncryptionKeyName/VersionName)","Fix client code that stores or passes key name and version name independently — keep them as one EDEK record","Verify with GET /v1/keyversion/{versionName} which key the version belongs to before decrypting"],"exampleFix":"# before: version from keyB sent with name keyA\n{\"name\":\"keyA\",\"iv\":\"...\",\"material\":\"...\"} -> /v1/keyversion/keyB@0/_eek\n# after: consistent pair\n{\"name\":\"keyB\",\"iv\":\"...\",\"material\":\"...\"} -> /v1/keyversion/keyB@0/_eek","handlingStrategy":"validation","validationCode":"KeyVersion kv = provider.getKeyVersion(ekv.getEncryptionKeyVersionName());\nif (kv != null && !kv.getName().equals(ekv.getEncryptionKeyName()))\n  throw new IllegalStateException(\"EDEK key/version mismatch: \" + ekv.getEncryptionKeyName() + \" vs \" + kv.getName());","typeGuard":null,"tryCatchPattern":"try { provider.decryptEncryptedKey(ekv); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"does not belong\")) { /* fix client pairing of name and version */ } else throw e; }","preventionTips":["Always take name and versionName from the same generateEncryptedKey response","Unit-test client serialization of EncryptedKeyVersion to catch field swaps","Validate the pairing before sending the decrypt request (code above)"],"tags":["hadoop-kms","key-version","http-400","data-integrity","key-management"],"backgroundTag":"entity-mismatch-validation","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}