{"record":{"id":"a38e850f943e6aa0","repo":"apache/hadoop","slug":"wrong-key-length-required-meta-getbitlength","errorCode":null,"errorMessage":"Wrong key length. Required ${meta.getBitLength()}, but got ${8 * material.length}","messagePattern":"Wrong key length\\. Required (.+?), but got (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/JavaKeyStoreProvider.java","lineNumber":518,"sourceCode":"    } catch (KeyStoreException e) {\n      throw new IOException(\"Can't store key \" + versionName + \" in \" + this,\n          e);\n    }\n    changed = true;\n    return new KeyVersion(name, versionName, material);\n  }\n\n  @Override\n  public KeyVersion rollNewVersion(String name,\n                                    byte[] material) throws IOException {\n    writeLock.lock();\n    try {\n      Metadata meta = getMetadata(name);\n      if (meta == null) {\n        throw new IOException(\"Key \" + name + \" not found\");\n      }\n      if (meta.getBitLength() != 8 * material.length) {\n        throw new IOException(\"Wrong key length. Required \" +\n            meta.getBitLength() + \", but got \" + (8 * material.length));\n      }\n      int nextVersion = meta.addVersion();\n      String versionName = buildVersionName(name, nextVersion);\n      return innerSetKeyVersion(name, versionName, material, meta.getCipher());\n    } finally {\n      writeLock.unlock();\n    }\n  }\n\n  @Override\n  public void flush() throws IOException {\n    Path newPath = constructNewPath(path);\n    Path oldPath = constructOldPath(path);\n    Path resetPath = path;\n    writeLock.lock();\n    try {\n      if (!changed) {","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/JavaKeyStoreProvider.java#L500-L536","documentation":"When rolling a new version, the supplied material must match the bit length stored in the key's existing Metadata: meta.getBitLength() == 8 * material.length. The provider enforces this so every version of a key stays interchangeable with earlier versions and with the recorded cipher metadata; the check runs before the version counter is incremented.","triggerScenarios":"Generating 128-bit material for a key originally created with setBitLength(256); sizing material from a fresh Options object instead of the key's actual metadata; copying generation code from another key with a different size.","commonSituations":"Clients that hard-code 16-byte material; keys created years ago with non-default lengths; refactors that lost the metadata-driven sizing.","solutions":["Read the required size from provider.getMetadata(name).getBitLength() and allocate bitLength/8 bytes","Prefer the one-arg rollNewVersion(name), which generates material from the stored metadata via generateKey","Centralize key-material generation in one helper that always sizes from Metadata"],"exampleFix":"// before\nbyte[] material = new byte[16]; // assumes 128-bit\nprovider.rollNewVersion(name, material);\n\n// after\nint bits = provider.getMetadata(name).getBitLength();\nbyte[] material = new byte[bits / Byte.SIZE];\nnew SecureRandom().nextBytes(material);\nprovider.rollNewVersion(name, material);","handlingStrategy":"validation","validationCode":"KeyProvider.Metadata meta = provider.getMetadata(name);\nif (meta == null) throw new IOException(\"key not found: \" + name);\nif (8 * material.length != meta.getBitLength()) {\n  material = new byte[meta.getBitLength() / Byte.SIZE];\n  new SecureRandom().nextBytes(material);\n}\nprovider.rollNewVersion(name, material);","typeGuard":null,"tryCatchPattern":"catch (IOException e) { if (String.valueOf(e.getMessage()).startsWith(\"Wrong key length\")) { // resize material from getMetadata(name).getBitLength()/8 and retry } else { throw e; } }","preventionTips":["Always size rollNewVersion material from stored Metadata, never from fresh Options","Prefer the one-arg rollNewVersion(name)","One shared key-material generation helper across the codebase"],"tags":["java","hadoop","key-provider","key-management","validation"],"backgroundTag":"key-length-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}