Netflix/zuul · error · TlsFatalAlert
unknown_psk_identity
unknown_psk_identity
Error message
Unknown or null client PSk identity
What it means
In ZuulPskServer.getExternalPSK, when the external TLS-PSK provider throws PskCreationFailureException with the TLS alert unknown_psk_identity, it is translated into a TlsFatalAlert(unknown_psk_identity, 'Unknown or null client PSk identity'). This means the PSK identity sent by the client in the TLS handshake does not match any identity known to the configured externalTlsPskProvider (or was null), so the TLS 1.3 handshake is aborted.
Solutions
- Ensure the client is configured with a PSK identity that the externalTlsPskProvider actually knows
- Check that the provider's key/identity store is loaded and in sync with what clients use
- Rotate or distribute PSKs consistently between client and server
- Log the received identity (as done via CLIENT_PSK_IDENTITY_ATTRIBUTE_KEY) to diagnose mismatched or empty identities
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at zuul-core/src/main/java/com/netflix/zuul/netty/server/psk/ZuulPskServer.java:170 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of Netflix/zuul@14bf53c52d (2026-09-07).
Data as JSON: /api/errors/46e8dac01d351f11.
Report an issue: GitHub.
Appendix: source
Thrown at zuul-core/src/main/java/com/netflix/zuul/netty/server/psk/ZuulPskServer.java:170
* SneakyThrows allows up to compile and it will throw the exception at runtime.
*/
@Override
@SneakyThrows
public TlsPSKExternal getExternalPSK(Vector clientPskIdentities) {
byte[] clientPskIdentity = ((PskIdentity) clientPskIdentities.get(0)).getIdentity();
byte[] psk;
try {
this.ctx
.channel()
.attr(TlsPskHandler.CLIENT_PSK_IDENTITY_ATTRIBUTE_KEY)
.set(new ClientPSKIdentityInfo(List.copyOf(Bytes.asList(clientPskIdentity))));
psk = externalTlsPskProvider.provide(
clientPskIdentity,
this.context.getSecurityParametersHandshake().getClientRandom());
} catch (PskCreationFailureException e) {
throw switch (e.getTlsAlertMessage()) {
case unknown_psk_identity ->
new TlsFatalAlert(AlertDescription.unknown_psk_identity, "Unknown or null client PSk identity");
case decrypt_error ->
new TlsFatalAlert(AlertDescription.decrypt_error, "Invalid or expired client PSk identity");
};
}
TlsSecret pskTlsSecret = getCrypto().createSecret(psk);
int prfAlgorithm = getPRFAlgorithm13(getSelectedCipherSuite());
return new BasicTlsPSKExternal(clientPskIdentity, pskTlsSecret, prfAlgorithm);
}
@Override
public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Throwable cause) {
super.notifyAlertRaised(alertLevel, alertDescription, message, cause);
Consumer<String> loggerFunc = (alertLevel == AlertLevel.fatal) ? LOGGER::error : LOGGER::debug;
loggerFunc.accept("TLS/PSK server raised alert: " + AlertLevel.getText(alertLevel) + ", "
+ AlertDescription.getText(alertDescription));
if (message != null) {
loggerFunc.accept("> " + message);
}View on GitHub (pinned to 14bf53c52d)