{"record":{"id":"9d4599bb60b719b6","repo":"apache/beam","slug":"private-key-cannot-be-null","errorCode":null,"errorMessage":"private key cannot be null","messagePattern":"private key cannot be null","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/BigtableConfigTranslator.java","lineNumber":423,"sourceCode":"        switch (credOptions.getCredentialType()) {\n          case DefaultCredentials:\n            // Veneer uses default credentials, so no need to reset here\n            break;\n          case P12:\n            String keyFile = ((CredentialOptions.P12CredentialOptions) credOptions).getKeyFile();\n            String serviceAccount =\n                ((CredentialOptions.P12CredentialOptions) credOptions).getServiceAccount();\n            try {\n              KeyStore keyStore = KeyStore.getInstance(\"PKCS12\");\n\n              try (FileInputStream fin = new FileInputStream(keyFile)) {\n                keyStore.load(fin, \"notasecret\".toCharArray());\n              }\n              PrivateKey privateKey =\n                  (PrivateKey) keyStore.getKey(\"privatekey\", \"notasecret\".toCharArray());\n\n              if (privateKey == null) {\n                throw new IllegalStateException(\"private key cannot be null\");\n              }\n              Credentials credentials =\n                  ServiceAccountJwtAccessCredentials.newBuilder()\n                      .setClientEmail(serviceAccount)\n                      .setPrivateKey(privateKey)\n                      .build();\n              builder.setCredentialFactory(FixedCredentialFactory.create(credentials));\n            } catch (GeneralSecurityException exception) {\n              throw new RuntimeException(\"exception while retrieving credentials\", exception);\n            }\n            break;\n          case SuppliedCredentials:\n            Credentials credentials =\n                ((CredentialOptions.UserSuppliedCredentialOptions) credOptions).getCredential();\n            builder.setCredentialFactory(FixedCredentialFactory.create(credentials));\n            break;\n          case SuppliedJson:\n            CredentialOptions.JsonCredentialsOptions jsonCredentialsOptions =","sourceCodeStart":405,"sourceCodeEnd":441,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/BigtableConfigTranslator.java#L405-L441","documentation":"When BigtableIO credentials are configured with a service account JSON key file, the code loads the key file into a PKCS12 KeyStore and extracts the 'privatekey' entry. If keyStore.getKey(...) returns null, the key file did not contain the expected private key alias, so an IllegalStateException('private key cannot be null') is thrown. This indicates the supplied file is not a valid Google service account PKCS12 key file.","triggerScenarios":"CredentialOptions.ServiceModelCredentialOptions with a key file path pointing to a file that is not a valid PKCS12 service account key, or a key file whose 'privatekey' alias entry is absent/renamed; also occurs if the keystore password differs from Google's fixed 'notasecret'.","commonSituations":"Passing a JSON-format service account key file where the translator expects a .p12 file; passing a non-credential file path; using a key file exported/converted in a way that drops the 'privatekey' alias; stale key files from old project setups.","solutions":["Ensure the key file is a .p12 (PKCS12) Google service account key, not a JSON key file; download the .p12 key from Cloud Console if needed","Prefer Application Default Credentials or UserSuppliedCredentialOptions instead of a raw key file","Verify the key file is not corrupted (open it with `keytool -list -keystore file.p12 -storepass notasecret` and confirm the 'privatekey' alias)","Re-create the service account key if the file predates key format changes or was hand-modified"],"exampleFix":"// before\n.withCredentialOptions(BeamBigtableIO.CredentialOptions.serviceAccountCredentialOptions(\"sa.json\", null))\n// after\n.withCredentialOptions(BeamBigtableIO.CredentialOptions.serviceAccountCredentialOptions(\"sa.p12\", serviceAccount))","handlingStrategy":"validation","validationCode":"File f = new File(keyPath);\ntry (FileInputStream fin = new FileInputStream(f)) {\n  KeyStore ks = KeyStore.getInstance(\"PKCS12\");\n  ks.load(fin, \"notasecret\".toCharArray());\n  if (ks.getKey(\"privatekey\", \"notasecret\".toCharArray()) == null) {\n    throw new IllegalArgumentException(\"Not a valid service account .p12: 'privatekey' alias missing\");\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer JSON key files with GoogleCredentials or Application Default Credentials over raw .p12 keystore options","Verify key files with keytool before using them in pipelines","Never pass JSON-format key files where a PKCS12 keystore is expected"],"tags":["java","bigtable","credentials","keystore"],"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"}