[ 
https://issues.apache.org/jira/browse/KAFKA-20644?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Pavel Zeger updated KAFKA-20644:
--------------------------------
    Priority: Minor  (was: Major)

> Connect’s RestServer assumes admin.listeners differ from listeners, silently 
> orphaning admin resources when they match
> ----------------------------------------------------------------------------------------------------------------------
>
>                 Key: KAFKA-20644
>                 URL: https://issues.apache.org/jira/browse/KAFKA-20644
>             Project: Kafka
>          Issue Type: Bug
>          Components: connect
>            Reporter: Pavel Zeger
>            Assignee: Pavel Zeger
>            Priority: Minor
>
> The Kafka Connect REST server lets operators expose admin endpoints on a 
> separate listener via admin.listeners. RestServer handles three intended 
> cases:
>  # admin.listeners unset (null) → admin resources are served on the main 
> listeners.
>  # admin.listeners set to an empty list → admin resources are disabled.
>  # admin.listeners set to values distinct from listeners → admin resources 
> are served on a separate Jetty connector.
> It does not handle a fourth case: when admin.listeners overlaps listeners 
> (shares a host:port). The code explicitly assumes the two are different - see 
> the TODOs in RestServer.initializeResources:
> {code:java}
> // 
> connect/runtime/src/main/java/org/apache/kafka/connect/runtime/rest/RestServer.java:245-246
> // TODO: we need to check if these listeners are same as 'listeners'
> // TODO: the following code assumes that they are different {code}
> There is no cross-validation of the two configs. admin.listeners is validated 
> only by anyNonDuplicateValues in RestServerConfig.java, checks for duplicates 
> within itself), and listeners uses ListenersValidator in 
> RestServerConfig.java. Neither compares the two lists.
>  
> What happens with overlapping config:
> {code:java}
> listeners=http://0.0.0.0:8083
> admin.listeners=http://0.0.0.0:8083 {code}
> RestServer.createConnectors unconditionally creates a Jetty ServerConnector 
> per main listener and a separate admin ServerConnector per admin listener. 
> With the config above this produces two connectors bound to the identical 
> host:port - a main connector named http_0.0.0.08083 (RestServer.java:180) and 
> an admin connector named Admin (RestServer.java:185). initializeResources 
> then binds the admin context to the @Admin connector via virtual host 
> (RestServer.java:270).
>  
> Because nothing enables SO_REUSEPORT, two listening sockets on the same 
> host:port collide. The expected result is that the second bind() fails at 
> jettyServer.start()  with BindException: Address already in use, which 
> initializeServer wraps as ConnectException("Unable to initialize REST 
> server") - i.e. the worker fails to start, with an error message that gives 
> no hint the real cause is admin.listeners overlapping listeners. Either way, 
> a plausible misconfiguration (a user wanting admin endpoints on the main port 
> may set the two equal, not realizing that leaving admin.listeners unset 
> already does exactly that) yields a confusing failure with no actionable 
> message.
> Proposed solutions
>  - Option A: treat an overlapping/identical admin.listeners as unset (inherit 
> admin resources onto the main listeners).
>  - Option B (recommended): fail fast. Validate early (before any connector is 
> built) that no admin.listeners entry shares a host:port with any listeners 
> entry, and throw a ConfigException directing the user to use distinct 
> host:port(s) or to leave admin.listeners unset to share the main listener.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to