{"record":{"id":"24371ddc501c639a","repo":"Netflix/zuul","slug":"decrypt-error","errorCode":"decrypt_error","errorMessage":"Invalid or expired client PSk identity","messagePattern":"Invalid or expired client PSk identity","errorType":"error_code","errorClass":"TlsFatalAlert","httpStatus":null,"severity":"error","filePath":"zuul-core/src/main/java/com/netflix/zuul/netty/server/psk/ZuulPskServer.java","lineNumber":172,"sourceCode":"    @Override\n    @SneakyThrows\n    public TlsPSKExternal getExternalPSK(Vector clientPskIdentities) {\n        byte[] clientPskIdentity = ((PskIdentity) clientPskIdentities.get(0)).getIdentity();\n        byte[] psk;\n        try {\n            this.ctx\n                    .channel()\n                    .attr(TlsPskHandler.CLIENT_PSK_IDENTITY_ATTRIBUTE_KEY)\n                    .set(new ClientPSKIdentityInfo(List.copyOf(Bytes.asList(clientPskIdentity))));\n            psk = externalTlsPskProvider.provide(\n                    clientPskIdentity,\n                    this.context.getSecurityParametersHandshake().getClientRandom());\n        } catch (PskCreationFailureException e) {\n            throw switch (e.getTlsAlertMessage()) {\n                case unknown_psk_identity ->\n                    new TlsFatalAlert(AlertDescription.unknown_psk_identity, \"Unknown or null client PSk identity\");\n                case decrypt_error ->\n                    new TlsFatalAlert(AlertDescription.decrypt_error, \"Invalid or expired client PSk identity\");\n            };\n        }\n        TlsSecret pskTlsSecret = getCrypto().createSecret(psk);\n        int prfAlgorithm = getPRFAlgorithm13(getSelectedCipherSuite());\n        return new BasicTlsPSKExternal(clientPskIdentity, pskTlsSecret, prfAlgorithm);\n    }\n\n    @Override\n    public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Throwable cause) {\n        super.notifyAlertRaised(alertLevel, alertDescription, message, cause);\n        Consumer<String> loggerFunc = (alertLevel == AlertLevel.fatal) ? LOGGER::error : LOGGER::debug;\n        loggerFunc.accept(\"TLS/PSK server raised alert: \" + AlertLevel.getText(alertLevel) + \", \"\n                + AlertDescription.getText(alertDescription));\n        if (message != null) {\n            loggerFunc.accept(\"> \" + message);\n        }\n        if (cause != null) {\n            LOGGER.error(\"TLS/PSK alert stacktrace\", cause);","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/Netflix/zuul/blob/14bf53c52dcf571894619ff65a674cbe2cce3ac6/zuul-core/src/main/java/com/netflix/zuul/netty/server/psk/ZuulPskServer.java#L154-L190","documentation":"In ZuulPskServer.getExternalPSK, when the external TLS-PSK provider throws PskCreationFailureException with the TLS alert decrypt_error, it is translated into a TlsFatalAlert(decrypt_error, 'Invalid or expired client PSk identity'). This means the client presented a known-format PSK identity but the key material could not be used: the PSK is wrong, corrupted, or has expired, so the TLS 1.3 handshake fails with a decrypt_error alert.","triggerScenarios":"Thrown at zuul-core/src/main/java/com/netflix/zuul/netty/server/psk/ZuulPskServer.java:172 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Verify the client's PSK key material matches the server's externalTlsPskProvider records","Check PSK expiry/rotation: reissue credentials if the identity's validity window has lapsed","Ensure clocks are synchronized if expiry is time-based","Confirm no TLS version/cipher-suite mismatch is corrupting key derivation between client and server"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"14bf53c52dcf571894619ff65a674cbe2cce3ac6","analyzedAt":"2026-09-07T10:00:54.873Z","contentChangedAt":"2026-09-07T10:00:54.873Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}