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

  1. Ensure the client is configured with a PSK identity that the externalTlsPskProvider actually knows
  2. Check that the provider's key/identity store is loaded and in sync with what clients use
  3. Rotate or distribute PSKs consistently between client and server
  4. 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)