{"record":{"id":"82f0e5136c134ca7","repo":"apache/pulsar","slug":"failed-to-load-private-key-from-privatekey-or-priv","errorCode":null,"errorMessage":"Failed to load private key from privateKey or privateKeyPath field","messagePattern":"Failed to load private key from privateKey or privateKeyPath field","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"critical","filePath":"pulsar-client-auth-athenz/src/main/java/org/apache/pulsar/client/impl/auth/AuthenticationAthenz.java","lineNumber":239,"sourceCode":"        if (isNotBlank(authParams.get(\"x509CertChain\"))) {\n            // When using Copper Argos\n            checkRequiredParams(authParams, \"privateKey\", \"caCert\", \"providerDomain\");\n            // Absolute paths are required to generate a key refresher, so if these are relative paths, convert them\n            this.x509CertChainPath = getAbsolutePathFromUrl(authParams.get(\"x509CertChain\"));\n            this.privateKeyPath = getAbsolutePathFromUrl(authParams.get(\"privateKey\"));\n            this.caCertPath = getAbsolutePathFromUrl(authParams.get(\"caCert\"));\n        } else {\n            checkRequiredParams(authParams, \"tenantDomain\", \"tenantService\", \"providerDomain\");\n\n            // privateKeyPath is deprecated, this is for compatibility\n            if (isBlank(authParams.get(\"privateKey\")) && isNotBlank(authParams.get(\"privateKeyPath\"))) {\n                this.privateKey = loadPrivateKey(authParams.get(\"privateKeyPath\"));\n            } else {\n                this.privateKey = loadPrivateKey(authParams.get(\"privateKey\"));\n            }\n\n            if (this.privateKey == null) {\n                throw new IllegalArgumentException(\n                        \"Failed to load private key from privateKey or privateKeyPath field\");\n            }\n        }\n\n        if (isNotBlank(authParams.get(\"athenzConfPath\"))) {\n            System.setProperty(\"athenz.athenz_conf\", authParams.get(\"athenzConfPath\"));\n        }\n        if (isNotBlank(authParams.get(\"principalHeader\"))) {\n            System.setProperty(\"athenz.auth.principal.header\", authParams.get(\"principalHeader\"));\n        }\n        if (isNotBlank(authParams.get(\"roleHeader\"))) {\n            this.roleHeader = authParams.get(\"roleHeader\");\n            System.setProperty(\"athenz.auth.role.header\", this.roleHeader);\n        }\n        if (isNotBlank(authParams.get(\"ztsUrl\"))) {\n            this.ztsUrl = authParams.get(\"ztsUrl\");\n        }\n        if (isNotBlank(authParams.get(\"ztsProxyUrl\"))) {","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-auth-athenz/src/main/java/org/apache/pulsar/client/impl/auth/AuthenticationAthenz.java#L221-L257","documentation":"After parsing authParams, setAuthParams resolves the private key from either the privateKey or privateKeyPath field. If both fields are absent/blank, or loadPrivateKey returns null (unreadable/unparseable key), AuthenticationAthenz throws IllegalArgumentException('Failed to load private key from privateKey or privateKeyPath field').","triggerScenarios":"configure() called with JSON missing both 'privateKey' and 'privateKeyPath' entries, or with values that loadPrivateKey cannot resolve (bad URL scheme, missing file, unparseable PEM).","commonSituations":"Athenz config copied from docs with placeholder paths; key file moved or deleted; typos like 'privatekey' or 'private_key' in the JSON keys; key data URI missing the data: prefix.","solutions":["Add a valid 'privateKey' entry (e.g. 'data:application/x-pem-file;base64,<key>') or a 'privateKeyPath' file URL ('file:///path/to/key.pem') to authParams","Verify the referenced file/URL exists and contains a parseable PEM private key","Check JSON key spelling — must be exactly 'privateKey' or 'privateKeyPath'"],"exampleFix":"// before\n{\"tenant\":\"t\",\"service\":\"s\"}\n// after\n{\"tenant\":\"t\",\"service\":\"s\",\"privateKeyPath\":\"file:///etc/pulsar/athenz_priv_key.pem\"}","handlingStrategy":"validation","validationCode":"Map<String,String> params = new ObjectMapper().readValue(json, new TypeReference<Map<String,String>>(){});\nString key = params.getOrDefault(\"privateKey\", params.get(\"privateKeyPath\"));\nif (key == null || key.isBlank()) {\n    throw new IllegalArgumentException(\"athenz authParams needs 'privateKey' or 'privateKeyPath'\");\n}\nif (key.startsWith(\"file:\")) {\n    if (!Files.isReadable(Paths.get(URI.create(key)))) throw new IllegalArgumentException(\"key file missing/unreadable\");\n}","typeGuard":"boolean hasPrivateKey(Map<String,String> p) {\n    return p.containsKey(\"privateKey\") || p.containsKey(\"privateKeyPath\");\n}","tryCatchPattern":"try {\n    authentication.configure(authParamsJson);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Failed to load private key\")) {\n        log.error(\"Check 'privateKey'/'privateKeyPath' in authParams and that the key file exists\");\n    }\n    throw e;\n}","preventionTips":["Verify the key file exists and is readable by the process user at startup","Use exact JSON key names: 'privateKey' and 'privateKeyPath'","Prefer file:/// URLs in 'privateKeyPath' over hand-built data: URIs unless base64 is verified"],"tags":["java","athenz","private-key","auth-config"],"backgroundTag":"missing-credential-config","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}