{"record":{"id":"675707bccf24722d","repo":"quarkusio/quarkus","slug":"jdk-provider-does-not-support-s-failure-behavior","errorCode":null,"errorMessage":"JDK provider does not support %s failure behavior","messagePattern":"JDK provider does not support (.+?) failure behavior","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"extensions/netty/runtime/src/main/java/io/quarkus/netty/runtime/graal/NettySubstitutions.java","lineNumber":365,"sourceCode":"            case ALPN:\n                if (isServer) {\n                    // GRAAL RC9 bug: https://github.com/oracle/graal/issues/813\n                    //                switch(config.selectorFailureBehavior()) {\n                    //                case FATAL_ALERT:\n                    //                    return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols());\n                    //                case NO_ADVERTISE:\n                    //                    return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols());\n                    //                default:\n                    //                    throw new UnsupportedOperationException(new StringBuilder(\"JDK provider does not support \")\n                    //                    .append(config.selectorFailureBehavior()).append(\" failure behavior\").toString());\n                    //                }\n                    SelectorFailureBehavior behavior = config.selectorFailureBehavior();\n                    if (behavior == SelectorFailureBehavior.FATAL_ALERT) {\n                        return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols());\n                    } else if (behavior == SelectorFailureBehavior.NO_ADVERTISE) {\n                        return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols());\n                    } else {\n                        throw new UnsupportedOperationException(new StringBuilder(\"JDK provider does not support \")\n                                .append(config.selectorFailureBehavior()).append(\" failure behavior\").toString());\n                    }\n                } else {\n                    switch (config.selectedListenerFailureBehavior()) {\n                        case ACCEPT:\n                            return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols());\n                        case FATAL_ALERT:\n                            return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols());\n                        default:\n                            throw new UnsupportedOperationException(new StringBuilder(\"JDK provider does not support \")\n                                    .append(config.selectedListenerFailureBehavior()).append(\" failure behavior\")\n                                    .toString());\n                    }\n                }\n            default:\n                throw new UnsupportedOperationException(\n                        new StringBuilder(\"JDK provider does not support \").append(config.protocol())\n                                .append(\" protocol\")","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/netty/runtime/src/main/java/io/quarkus/netty/runtime/graal/NettySubstitutions.java#L347-L383","documentation":"When the JDK SSL provider is used, Netty's ALPN support (here the Quarkus native substitution's toNegotiator) can only map SelectorFailureBehavior.FATAL_ALERT and NO_ADVERTISE onto JDK TLS semantics. Any other selector failure behavior — i.e. ACCEPT — is unrepresentable, so an UnsupportedOperationException is thrown.","triggerScenarios":"ApplicationProtocolConfig with protocol ALPN, selectorFailureBehavior() returning SelectorFailureBehavior.ACCEPT (anything other than FATAL_ALERT/NO_ADVERTISE), while using SslProvider.JDK — hit during SslContext construction.","commonSituations":"Sharing an ApplicationProtocolConfig between OpenSSL and JDK providers where ACCEPT behavior was chosen; upgrading/migrating from tcnative to JDK provider without revisiting ALPN config; defaulting selectors in copied HTTP/2 bootstrap code.","solutions":["Change selectorFailureBehavior to FATAL_ALERT or NO_ADVERTISE in the ApplicationProtocolConfig.","Use the OpenSSL provider, which supports all SelectorFailureBehavior values.","Create two configs: one for JDK provider constraints and one for OpenSSL."],"exampleFix":"// before\nApplicationProtocolConfig apn = new ApplicationProtocolConfig(\n    ApplicationProtocolConfig.Protocol.ALPN,\n    ApplicationProtocolConfig.SelectorFailureBehavior.ACCEPT,\n    ApplicationProtocolConfig.SelectedListenerFailureBehavior.FATAL_ALERT,\n    HttpVersion.HTTP_2.protocolName());\n// after\nApplicationProtocolConfig apn = new ApplicationProtocolConfig(\n    ApplicationProtocolConfig.Protocol.ALPN,\n    ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE,\n    ApplicationProtocolConfig.SelectedListenerFailureBehavior.FATAL_ALERT,\n    HttpVersion.HTTP_2.protocolName());","handlingStrategy":"validation","validationCode":"if (config.selectorFailureBehavior() == SelectorFailureBehavior.ACCEPT) {\n    throw new IllegalArgumentException(\"SelectorFailureBehavior.ACCEPT unsupported with JDK provider\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    ctx = builder.build();\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage().contains(\"failure behavior\")) {\n        ctx = builderWithFixedAlpnConfig().build();\n    } else { throw e; }\n}","preventionTips":["Use only FATAL_ALERT or NO_ADVERTISE selector failure behavior with SslProvider.JDK","Document provider-specific ApplicationProtocolConfig constraints near the bootstrap code","Prefer OpenSSL provider when full ALPN behavior control is needed"],"tags":["netty","ssl","alpn","jdk","http2"],"backgroundTag":"alpn-unsupported-jdk-provider","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}