Skip to main content
Preview functionality. This is a preview feature and is subject to change. The existing listener configuration remains fully supported.
Gateway supports multiple listeners, allowing you to expose different network endpoints with independent security protocols, routing strategies and network bindings. Use multiple listeners when you need to:
  • Expose internal and external endpoints (for example, PLAINTEXT for internal services, SASL_SSL for external clients)
  • Support Kubernetes deployments with separate ClusterIP and LoadBalancer services
  • Serve different client populations with different security requirements

Understand configuration modes

Gateway detects the configuration mode automatically at startup based on the environment variables you set:
ModeTriggerUse case
Multi-listenerAny GATEWAY_LISTENER_* env var is setMultiple listeners, advanced configuration
StandardStandard env vars like GATEWAY_PORT_STARTSingle listener deployments
Zero-configNo listener configurationLocal development and testing only
Standard mode will be deprecated once the multi-listener feature is stabilized. Multi-listener mode will become the new standard for all deployments.

Zero-config mode

If you don’t set any listener or networking environment variables, Gateway configures itself automatically. It creates a single listener with port routing. Ports start from 6969, with one port per broker plus two extra for headroom. The listener uses the same security protocol as the backing Kafka cluster. If you don’t set GATEWAY_SECURITY_MODE, Gateway infers the security mode from the protocol: KAFKA_MANAGED for SASL protocols, GATEWAY_MANAGED for others.
Do not use zero-config mode in production. Always configure your listeners explicitly for production deployments.

Configure listeners

Define each listener using environment variables with the pattern GATEWAY_LISTENER_<NAME>_<PROPERTY>, where <NAME> is a label you choose (for example, EXTERNAL, INTERNAL).
In multi-listener mode, GATEWAY_SECURITY_MODE is required. It is not automatically inferred. Set it explicitly to GATEWAY_MANAGED or KAFKA_MANAGED.
VariableDescriptionDefault
GATEWAY_LISTENER_<NAME>_SECURITY_PROTOCOLSecurity protocol: PLAINTEXT, SSL, SASL_SSL, or SASL_PLAINTEXTRequired
GATEWAY_LISTENER_<NAME>_ROUTINGRouting mechanism: port or sniRequired
GATEWAY_LISTENER_<NAME>_PORTSPort specification (comma-separated for multiple ranges)Required
GATEWAY_LISTENER_<NAME>_BIND_ADDRESSNetwork interface to bind to0.0.0.0
GATEWAY_LISTENER_<NAME>_ADVERTISED_HOSTHostname returned to clientsSystem hostname or localhost
GATEWAY_LISTENER_<NAME>_ADVERTISED_HOST_PATTERNTemplate for per-broker hostnames. Only used when routing is set to sni.broker-{{physicalCluster}}-{{nodeId}}.{{advertisedHost}}
GATEWAY_LISTENER_<NAME>_BOOTSTRAP_HOST_PATTERNTemplate for bootstrap hostname. Only used when routing is set to sni.Derived from ADVERTISED_HOST_PATTERN, or bootstrap-{{physicalCluster}}.{{advertisedHost}} if not set
Listener names have to start with a letter and contain only alphanumeric characters. Don’t use underscores or special characters — a name like MY_LISTENER would be ambiguous since underscores are already used as delimiters in GATEWAY_LISTENER_<NAME>_<PROPERTY>.

Specify ports

The format of GATEWAY_LISTENER_<NAME>_PORTS depends on the routing mechanism.

Port routing

Gateway assigns one port per broker, in order, starting from broker ID GATEWAY_MIN_BROKERID. Make sure to define enough ports to cover all your brokers. Ports can be defined as ranges, individual values, or a combination of both, separated by commas:
GATEWAY_LISTENER_EXTERNAL_PORTS=9092-9095
GATEWAY_LISTENER_EXTERNAL_PORTS=9092,9093,9094,9095
GATEWAY_LISTENER_EXTERNAL_PORTS=9092-9093,9100,9200
If the advertised ports differ from local ports (for example, when running behind a NAT or in Docker), use the advertised:local format:
GATEWAY_LISTENER_EXTERNAL_PORTS=29092-29095:9092-9095
You can mix ranges and individual ports with local mappings. For example, with GATEWAY_MIN_BROKERID=0 and three brokers:
# Broker 0 → advertised 29092, local 9092
# Broker 1 → advertised 29093, local 9093
# Broker 2 → advertised 29100, local 9100
GATEWAY_LISTENER_EXTERNAL_PORTS=29092-29093:9092-9093,29100:9100

SNI routing

With SNI routing, Gateway listens on a single port and routes traffic based on the hostname in the TLS handshake. SNI routing requires a TLS-based security protocol (SSL or SASL_SSL) and proper DNS and TLS certificates for each broker hostname.
GATEWAY_LISTENER_EXTERNAL_PORTS=9192
If the advertised port differs from the local port (for example, behind a load balancer exposing port 443), use the advertised:local format:
GATEWAY_LISTENER_EXTERNAL_PORTS=443:9192

Configure host patterns

With SNI routing, each broker needs a unique hostname so clients can reach it. Set GATEWAY_LISTENER_<NAME>_ADVERTISED_HOST_PATTERN using these template variables:
TemplateDescriptionExample value
{{nodeId}}Broker ID0, 1, 2
{{physicalCluster}}Backend cluster namemain
{{virtualCluster}}Virtual cluster namemy-partner
{{advertisedHost}}Listener’s advertised hostgateway.example.com
If not set, the default pattern is broker-{{physicalCluster}}-{{nodeId}}.{{advertisedHost}}. Clients also need a bootstrap hostname for the initial connection before broker discovery. You can set it with GATEWAY_LISTENER_<NAME>_BOOTSTRAP_HOST_PATTERN, or let Gateway derive it automatically from the advertised host pattern by removing the {{nodeId}} part and its adjacent separator (., -, or _). When the advertised host pattern is also not set, the default bootstrap pattern is bootstrap-{{physicalCluster}}.{{advertisedHost}}. Your TLS certificates and DNS records have to cover both the broker and bootstrap hostnames.

Choose a routing strategy

SetupRecommendedWhy
Single cluster, dev/testPortSimple, no DNS or certificates required
Single cluster, productionPort or SNIBoth work well; SNI simplifies port management
Multi-cluster, dev/testPortAcceptable for ephemeral environments
Multi-cluster, productionSNIPort mapping shifts when clusters change
Avoid port routing with multiple clusters in production. Adding or removing a cluster shifts all port mappings, which can break existing client connections.

Current limitations

  • Shared SSL configuration: All listeners share the same SSL configuration. To serve different certificates per listener, include all of them in the global keystore — Gateway selects the right one based on SNI during the TLS handshake.
  • Shared SASL mechanisms: All SASL listeners share the same set of enabled SASL mechanisms. You can’t enable different mechanisms per listener (for example, OAUTHBEARER-only for external, PLAIN-only for internal).
  • Global security mode: All listeners share the same GATEWAY_SECURITY_MODE. You can’t mix GATEWAY_MANAGED and KAFKA_MANAGED across listeners. If your use case requires both modes, deploy separate Gateway instances.
  • Internal load balancing: Internal load balancing is a global setting, not per listener. When enabled, all listeners have to share the same advertised host. If listeners have different advertised hosts, disable internal load balancing or Gateway will fail to start.

Examples

These examples show listener configuration only. You also need to set KAFKA_BOOTSTRAP_SERVERS and other Kafka connection variables for Gateway to connect to your cluster. See Gateway environment variables for the full reference.
A single listener using port routing, suitable for local development or simple deployments:
GATEWAY_SECURITY_MODE=GATEWAY_MANAGED
GATEWAY_LISTENER_EXTERNAL_SECURITY_PROTOCOL=PLAINTEXT
GATEWAY_LISTENER_EXTERNAL_ROUTING=port
GATEWAY_LISTENER_EXTERNAL_PORTS=9092-9095:29092-29095
GATEWAY_LISTENER_EXTERNAL_ADVERTISED_HOST=localhost

Verify your configuration

Check the Gateway startup logs to confirm your listeners are configured correctly. Gateway logs the computed configuration at startup, including all registered listeners, their ports and routing mechanisms. To make sure the values were set correctly, check the startup logs:
docker logs <YOUR_GATEWAY_CONTAINER>
Look for listener entries in the Computed configuration output. Each listener should appear with its name, ports, security protocol and routing mechanism. If a listener is missing or has unexpected values, verify that the environment variables follow the GATEWAY_LISTENER_<NAME>_<PROPERTY> naming pattern and that the listener name contains only alphanumeric characters.

Switch from standard configuration

If you’re currently using standard environment variables and want to adopt the multi-listener configuration, use this mapping as a reference. Standard variables internally create a single listener named DEFAULT.
Standard variableMulti-listener equivalent
GATEWAY_BIND_HOSTGATEWAY_LISTENER_<NAME>_BIND_ADDRESS
GATEWAY_ADVERTISED_HOSTGATEWAY_LISTENER_<NAME>_ADVERTISED_HOST
GATEWAY_PORT_START and GATEWAY_PORT_COUNTGATEWAY_LISTENER_<NAME>_PORTS
GATEWAY_ADVERTISED_SNI_PORTGATEWAY_LISTENER_<NAME>_PORTS (use advertised:local format)
GATEWAY_ROUTING_MECHANISMGATEWAY_LISTENER_<NAME>_ROUTING (host is now called sni)
GATEWAY_SECURITY_PROTOCOLGATEWAY_LISTENER_<NAME>_SECURITY_PROTOCOL
GATEWAY_ADVERTISED_HOST_PREFIX and GATEWAY_SNI_HOST_SEPARATORGATEWAY_LISTENER_<NAME>_ADVERTISED_HOST_PATTERN and GATEWAY_LISTENER_<NAME>_BOOTSTRAP_HOST_PATTERN
For example, this standard configuration:
GATEWAY_BIND_HOST=0.0.0.0
GATEWAY_ADVERTISED_HOST=gateway.example.com
GATEWAY_PORT_START=6969
GATEWAY_PORT_COUNT=5
GATEWAY_ADVERTISED_SNI_PORT=443
GATEWAY_ROUTING_MECHANISM=host
GATEWAY_SECURITY_PROTOCOL=SASL_SSL
GATEWAY_ADVERTISED_HOST_PREFIX=gateway
GATEWAY_SNI_HOST_SEPARATOR=-
Becomes:
GATEWAY_LISTENER_DEFAULT_BIND_ADDRESS=0.0.0.0
GATEWAY_LISTENER_DEFAULT_ADVERTISED_HOST=gateway.example.com
GATEWAY_LISTENER_DEFAULT_PORTS=6969-6973:443
GATEWAY_LISTENER_DEFAULT_ROUTING=sni
GATEWAY_LISTENER_DEFAULT_SECURITY_PROTOCOL=SASL_SSL
GATEWAY_LISTENER_DEFAULT_ADVERTISED_HOST_PATTERN=gateway{{physicalCluster}}{{nodeId}}-{{advertisedHost}}
GATEWAY_LISTENER_DEFAULT_BOOTSTRAP_HOST_PATTERN=gateway{{physicalCluster}}-{{advertisedHost}}
GATEWAY_PORT_START=6969 with GATEWAY_PORT_COUNT=5 maps to the port range 6969-6973. The :443 suffix replaces GATEWAY_ADVERTISED_SNI_PORT=443, meaning Gateway listens locally on ports 6969-6973 but advertises port 443 to clients. GATEWAY_ADVERTISED_HOST_PREFIX and GATEWAY_SNI_HOST_SEPARATOR are replaced by explicit host patterns using template variables. When switching, keep in mind:
  1. Set the security mode explicitly: GATEWAY_SECURITY_MODE is required in multi-listener mode and is not automatically inferred.
  2. SNI host patterns have changed: The default advertised host pattern is now broker-{{physicalCluster}}-{{nodeId}}.{{advertisedHost}}, which differs from the previous behavior based on GATEWAY_ADVERTISED_HOST_PREFIX (default: broker) and GATEWAY_SNI_HOST_SEPARATOR (default: -). If your DNS records and TLS certificates match the old pattern, either update them or set the pattern explicitly to match. For example, to reproduce the previous default behavior:
    GATEWAY_LISTENER_<NAME>_ADVERTISED_HOST_PATTERN=broker{{physicalCluster}}{{nodeId}}-{{advertisedHost}}
    GATEWAY_LISTENER_<NAME>_BOOTSTRAP_HOST_PATTERN=broker{{physicalCluster}}-{{advertisedHost}}
    
  3. mTLS users: Set GATEWAY_SSL_CLIENT_AUTH explicitly (it is no longer auto-inferred).