{"record":{"id":"b8e9949d4c7f856c","repo":"apache/beam","slug":"failed-to-initialize-cryptography-libraries-needed-for","errorCode":null,"errorMessage":"Failed to initialize cryptography libraries needed for GroupByEncryptedKey","messagePattern":"Failed to initialize cryptography libraries needed for GroupByEncryptedKey","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/GroupByEncryptedKey.java","lineNumber":162,"sourceCode":"    private transient SecretKeySpec secretKeySpec;\n    private transient java.security.SecureRandom generator;\n\n    EncryptMessage(Secret hmacKey, Coder<K> keyCoder, Coder<V> valueCoder) {\n      this.hmacKey = hmacKey;\n      this.keyCoder = keyCoder;\n      this.valueCoder = valueCoder;\n    }\n\n    @Setup\n    public void setup() {\n      try {\n        byte[] secretBytes = java.util.Base64.getUrlDecoder().decode(this.hmacKey.getSecretBytes());\n        this.mac = Mac.getInstance(\"HmacSHA256\");\n        this.mac.init(new SecretKeySpec(secretBytes, \"HmacSHA256\"));\n        this.cipher = Cipher.getInstance(\"AES/GCM/NoPadding\");\n        this.secretKeySpec = new SecretKeySpec(secretBytes, \"AES\");\n      } catch (Exception ex) {\n        throw new RuntimeException(\n            \"Failed to initialize cryptography libraries needed for GroupByEncryptedKey\", ex);\n      }\n      this.generator = new java.security.SecureRandom();\n    }\n\n    @ProcessElement\n    public void processElement(ProcessContext c) throws Exception {\n      byte[] encodedKey = encode(this.keyCoder, c.element().getKey());\n      byte[] encodedValue = encode(this.valueCoder, c.element().getValue());\n\n      byte[] hmac = this.mac.doFinal(encodedKey);\n\n      byte[] keyIv = new byte[12];\n      byte[] valueIv = new byte[12];\n      this.generator.nextBytes(keyIv);\n      this.generator.nextBytes(valueIv);\n      GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, keyIv);\n      this.cipher.init(Cipher.ENCRYPT_MODE, this.secretKeySpec, gcmParameterSpec);","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/GroupByEncryptedKey.java#L144-L180","documentation":"The encrypting DoFn's setup method initializes an HMAC-SHA256 Mac and an AES/GCM Cipher from the Base64-encoded secret in the provided HmacKey. Any failure — bad Base64, missing/unsupported JCE provider, invalid key length, or absent crypto provider — is wrapped in a RuntimeException with this message.","triggerScenarios":"Beam calls setup() when the DoFn starts on a worker; it throws if getSecretBytes() is not valid Base64 URL, the decoded bytes are not a valid AES/HMAC key length (e.g. wrong size for AES-128/192/256), or Cipher.getInstance(\"AES/GCM/NoPadding\") / Mac.getInstance(\"HmacSHA256\") is unavailable in the JVM.","commonSituations":"Passing a raw (non-Base64) secret string into the HmacKey; truncated or padded-incorrectly Base64; running on a JVM with restricted JCE policy or a stripped-down runtime lacking AES/GCM; key bytes of an unsupported length (e.g. 7 bytes).","solutions":["Verify the secret is valid standard Base64 URL (no whitespace/newlines) and decodes to a supported key length (16/24/32 bytes for AES)","Regenerate the key at exactly 32 bytes and Base64 URL-encode it before creating the HmacKey","Run on a JVM with a full JCE provider (check Cipher.getInstance(\"AES/GCM/NoPadding\") works in the worker image)","Inspect the wrapped cause (ex.getCause()) to pinpoint whether Base64 decoding, Mac.init, or Cipher.getInstance failed"],"exampleFix":"// before\nbyte[] raw = \"my-secret\".getBytes(); // 9 bytes, not Base64, wrong length\nHmacKey key = HmacKey.of(Base64.getUrlEncoder().encodeToString(raw));\n// after\nbyte[] keyBytes = new byte[32];\nnew SecureRandom().nextBytes(keyBytes);\nHmacKey key = HmacKey.of(Base64.getUrlEncoder().encodeToString(keyBytes));","handlingStrategy":"validation","validationCode":"byte[] secret = Base64.getUrlDecoder().decode(secretB64);\nif (secret.length != 16 && secret.length != 24 && secret.length != 32)\n  throw new IllegalArgumentException(\"AES key must be 16/24/32 bytes\");\njavax.crypto.Mac.getInstance(\"HmacSHA256\"); // verify provider availability pre-deploy","typeGuard":null,"tryCatchPattern":"try {\n  result = input.apply(GroupByEncryptedKey.of(hmacKey));\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Failed to initialize cryptography\")) {\n    throw new IllegalStateException(\"Check secret Base64 encoding/key length/JCE provider\", e);\n  }\n  throw e;\n}","preventionTips":["Generate 32-byte keys and always Base64 URL-encode them","Test key setup in a plain JVM unit test before pipeline submission","Use the same key material on encrypt and decrypt sides"],"tags":["apache-beam","java","cryptography","aes-gcm","hmac","initialization"],"backgroundTag":"module-init-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}