{"record":{"id":"23beebbfdae5c5db","repo":"apache/beam","slug":"the-private-key-is-encrypted-but-no-private-key-key","errorCode":null,"errorMessage":"The private key is encrypted but no private key key passphrase has been provided.","messagePattern":"The private key is encrypted but no private key key passphrase has been provided\\.","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/snowflake/src/main/java/org/apache/beam/sdk/io/snowflake/KeyPairUtils.java","lineNumber":58,"sourceCode":"\npublic class KeyPairUtils {\n  private static final String ENCRYPTED_PRIVATE_KEY = \"ENCRYPTED PRIVATE KEY\";\n  private static final String UNENCRYPTED_PRIVATE_KEY = \"PRIVATE KEY\";\n\n  private enum KeyEncryptionState {\n    ENCRYPT,\n    UNENCRYPTED,\n    UNKNOWN\n  }\n\n  @SuppressFBWarnings(\"DCN_NULLPOINTER_EXCEPTION\")\n  public static PrivateKey preparePrivateKey(String privateKey, String privateKeyPassphrase) {\n    try {\n      KeyFactory keyFactory = KeyFactory.getInstance(\"RSA\");\n      KeyEncryptionState encryptionState = guessKeyEncryptionState(privateKey);\n      if (encryptionState == KeyEncryptionState.ENCRYPT\n          && Strings.isNullOrEmpty(privateKeyPassphrase)) {\n        throw new RuntimeException(\n            \"The private key is encrypted but no private key key passphrase has been provided.\");\n      }\n\n      if (encryptionState == KeyEncryptionState.UNENCRYPTED\n          && !Strings.isNullOrEmpty(privateKeyPassphrase)) {\n        throw new RuntimeException(\n            \"The private key is unencrypted but private key key passphrase has been provided.\");\n      }\n\n      byte[] decoded;\n\n      if (encryptionState == KeyEncryptionState.UNKNOWN) {\n        decoded = Base64.decode(privateKey);\n      } else {\n        PemReader pr = new PemReader(new StringReader(privateKey));\n        PemObject pemObject = pr.readPemObject();\n        decoded = pemObject.getContent();\n        pr.close();","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/snowflake/src/main/java/org/apache/beam/sdk/io/snowflake/KeyPairUtils.java#L40-L76","documentation":"KeyPairUtils.preparePrivateKey inspects the PEM header to detect encryption. If the key is encrypted (ENCRYPT state) but privateKeyPassphrase is null or empty, it throws this RuntimeException, because it cannot decrypt the key for Snowflake key-pair authentication.","triggerScenarios":"Calling preparePrivateKey with an encrypted PKCS#8 PEM (\"ENCRYPTED PRIVATE KEY\" header, e.g. produced by newer OpenSSL) and passing null/\"\" as passphrase.","commonSituations":"Generating a key with openssl genpkey (encrypted by default) and forgetting to pass the passphrase in the Snowflake config; passphrase stored in a separate env var that is unset; key regenerated encrypted after previously being unencrypted.","solutions":["Provide the passphrase via Snowflake key-pair config (privateKeyPassphrase / sfPrivateKeyPassphrase property).","Regenerate the key unencrypted if the passphrase is not needed: openssl pkcs8 -topk8 -nocrypt ... or `openssl genpkey -algorithm RSA` with -aes... omitted / use `openssl rsa -in key.pem -out key-unenc.pem`.","Check that the passphrase env var/secret is actually populated at runtime (not empty string)."],"exampleFix":"// before\nKeyPairUtils.preparePrivateKey(privateKeyPem, null);\n\n// after\nKeyPairUtils.preparePrivateKey(privateKeyPem, System.getenv(\"SNOWFLAKE_KEY_PASSPHRASE\"));","handlingStrategy":"validation","validationCode":"boolean encrypted = pem.contains(\"BEGIN ENCRYPTED PRIVATE KEY\");\nif (encrypted && (passphrase == null || passphrase.isEmpty())) {\n  throw new IllegalStateException(\"Passphrase required for encrypted private key\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  KeyPair kp = KeyPairUtils.preparePrivateKey(pem, passphrase);\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"passphrase\")) {\n    // surface config error: prompt/require SNOWFLAKE_KEY_PASSPHRASE\n  }\n  throw e;\n}","preventionTips":["Read the PEM header and only set a passphrase when the key is encrypted.","Load the passphrase from a secret manager and assert non-empty at startup.","Document how keys are generated (encrypted vs -nocrypt) in team runbooks."],"tags":["snowflake","private-key","authentication","configuration"],"backgroundTag":"missing-credentials","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"}