Configure and Deploy Confluent Private Cloud Gateway

This guide provides instructions for configuring and deploying Confluent Private Cloud Gateway (Confluent Gateway) using Docker.

Confluent Gateway runs as a stateless service, often as a set of containerized instances within the target environment (for example, Confluent for Kubernetes, VM clusters, or cloud-native platforms).

A separate guide is provided for the security-related tasks. See Configure Security for Confluent Private Cloud Gateway:

  • Configure secret stores

  • Configure SSL

  • Configure passwords

  • Configure authentication swapping

Confluent Gateway supports deployment on-premises, in private cloud VPCs, or in hybrid environments.

The high-level steps to deploy Confluent Gateway are:

  1. Configure Confluent Gateway to connect to Kafka clusters, specifying authentication, routing policies, and security policies according to your organizational needs.

    Additionally, Configure security for the Confluent Gateway.

  2. Provision the Confluent Gateway service using the configuration settings from the previous step.

  3. Reconfigure clients to communicate with the Confluent Gateway endpoint.

    This simplifies credential management and strengthens overall security posture.

Requirements and considerations

Before you begin, make sure that the following requirements and considerations are satisfied:

  • System requirements

    • CPU and memory

      • Minimum: 2 vCPUs, 4 GB RAM

      • Recommended: 4 vCPUs, 8 GB RAM

    • Network throughput: 45 MB/sec of sustained workload for a 1 Gigabit Link (1Gbps)

    • Storage: 10 GB of disk space

  • Docker

    For Docker-based deployments, Docker Desktop or Docker Engine with Compose v2 is installed (Docker Engine 20.x or later is recommended).

  • CFK and Confluent Platform

    For Confluent for Kubernetes (CFK)-based deployments, ensure your Kubernetes environment is set up and CFK and Confluent Platform are installed.

    Use the appropriate version of CFK that supports your Confluent Platform and Confluent Gateway requirements.

  • Network access

    The Confluent Gateway container must have access to necessary Kafka clusters. Configure firewall ports for bidirectional traffic as needed.

Configure Confluent Gateway using Docker Compose

Provide the configuration settings in a Docker Compose YAML file. docker-compose.yaml is used as an example in this guide.

The top-level layout for the Confluent Gateway configuration file is as follows:

gateway:
  image:                  --- [1]
  name:                   --- [2]
  streamingDomains: []    --- [3]
  secretStores: []        --- [4]
  routes: []              --- [5]
  admin: {}               --- [6]
  advanced: {}            --- [7]
  • [1] The Gateway Docker image in the pattern: confluentinc/cpc-gateway:<version-tag>. <version-tag> is the Confluent Gateway version.

  • [2] The Gateway instance identifier.

  • [3] A list of streaming domains that represent Kafka clusters. For more information, see Streaming domains configuration.

  • [4] A list of credential stores. Required for authentication swapping. See Secret store configuration for details.

  • [5] A list of client routing rules. For more information, see Routes configuration.

  • [6] Admin and metrics configuration. For more information, see Administration and metrics configuration.

  • [7] Advanced settings.

Streaming domains configuration

Streaming domains are logical representations of your Kafka clusters in Confluent Gateway.

gateway:
  streamingDomains:
    - name:               --- [1]
      type:               --- [2]
      kafkaCluster:       --- [3]
        name:             --- [4]
        bootstrapServers: --- [5]
          - id:           --- [6]
            endpoint:     --- [7]
            ssl:          --- [8]
        nodeIdRanges:     --- [9]
          - name:         --- [10]
            start:        --- [11]
            end:          --- [12]
  • [1] A unique name for the streaming domain.

  • [2] The type of the streaming domain. Set to kafka by default.

  • [3] A Kafka cluster, including Confluent Server, Confluent Private Cloud Kafka, or Apache Kafka®, that the Confluent Gateway can route traffic to.

  • [4] The name of the Kafka cluster.

  • [5] A list of Kafka bootstrap servers in the format host:port. At minimum, one bootstrap server is required per Kafka cluster. For each listener, one can define one bootstrap server.

  • [6] A unique identifier for the bootstrap-server. Recommended to use the protocol, such as SASL_PLAINTEXT, SSL or PLAINTEXT_SASL_PLAIN for clear distinction between both TLS channel type and SASL mechanism.

  • [7] The bootstrap endpoint of the Kafka broker in the format, protocol://host:port

  • [8] Only required for SSL/SASL_SSL configuration.

    See the SSL configuration section for details.

  • [9] The node ID ranges. Only required for port-based broker identification. These should be the broker IDs defined in the Kafka deployment.

  • [10] The name of the node ID range.

  • [11] The start of the node ID range, inclusive.

  • [12] The end of the node ID range, inclusive.

An example configuration for a Confluent Gateway streaming domain:

streamingDomains:
  - name: sales # unique across gateway
    type: kafka # default: kafka
    kafkaCluster:
      name: sales-cluster # default: <streamingDomain.name>
      bootstrapServers:
        - id: PLAINTEXT-1
          endpoint: kafka0.example.com:9092
        - id: SASL_SSL-1
          endpoint: kafka0.example.com:9093
          ssl:  # required when using SASL_SSL/SSL
            ignoreTrust: false
            truststore:
              type: PKCS12  # default: JKS
              location: /opt/ssl/client-truststore.p12
              password:
                file: /opt/secrets/client-truststore.password
            keystore: # gateway's identity when needed
              type: PKCS12 # default: JKS
              location: /opt/ssl/gw-keystore.p12
              password:
                file: /opt/secrets/gw-keystore.password
              keyPassword:
                value: inline-password
      nodeIdRanges:
        - name: default
          start: 0              # inclusive
          end: 3                # inclusive
  • password can be a file path or an inline value.

  • ignoreTrust is used to skip certificate validation (not recommended for production). Other settings will be ignored if ignoreTrust is true

Routes configuration

Routes are Confluent Gateway endpoints where client applications connect to stream data.

Confluent Gateway uses routes to define how client applications connect to Kafka clusters. Clients connect to the Gateway as if it were a Kafka cluster, while the Gateway handles routing and governance.

gateway:
  routes:
    - name:                         --- [1]
      endpoint:                     --- [2]
      brokerIdentificationStrategy: --- [3]
        type:                       --- [4]
        pattern:                    --- [5]
      streamingDomain:              --- [6]
        name:                       --- [7]
        bootstrapServerId:          --- [8]
      security:                     --- [9]
      fence:                        --- [10]
  • [1] The unique name for the route.

  • [2] The host:port combination that Confluent Gateway will listen on. This is the external address clients use to bootstrap to the Kafka cluster.

  • [3] Specifies the strategy for mapping client requests to a specific Kafka broker.

  • [4] The type of broker identification strategy. Set to port (default) or host.

    • port strategy: Each Kafka broker is identified using a unique port number. This is the default strategy.

      Clients connect to different ports to reach specific brokers (for example, port 9092 to connect with broker-0, port 9093 to connect with broker-1).

      The nodeIdRanges for the streaming domain you set in Streaming domains configuration is used.

      nodeIdRanges should be present in all of the clusters associated with route’s streaming domain.

    • host strategy: Each Kafka broker is represented using a unique hostname.

      Clients use different host names to reach specific brokers (for example, broker-0.kafka.company.com, broker-1.kafka.company.com), and the gateway routes based on the SNI header.

      The pattern setting ([5]) is used.

  • [5] The pattern for the broker identification strategy. Required if the type ([4]) is host. For example, broker-$(nodeId).eu-gw.sales.example.com:9092.

  • [6] The reference to a streaming domain.

  • [7] The name of the streaming domain. Must be a valid name from the gateway.streamingDomains[].name.

  • [8] The bootstrap server ID. Must match kafkaCluster.bootstrapServers[].id.

  • [9] The security configuration. See Configure Security for Confluent Private Cloud Gateway section for details.

  • [10] Optional. The fencing filter configuration. See Fencing filter for details.

An example configuration for Confluent Gateway routes:

gateway:
 routes:
   - name: eu-sales
     endpoint: eu-gw.sales.example.com:9092
     brokerIdentificationStrategy:
       type: host
       pattern: broker-$(nodeId).eu-gw.sales.example.com:9092
     streamingDomain:
       name: sales
       bootstrapServerId: SASL_SSL-1

Configure route filters

Filters allow you to control and manage traffic flow for specific routes in Confluent Gateway. You can apply filters at the route level to enforce policies, block or allow requests, and customize error handling for different scenarios.

Fencing filter

The fencing filter in Confluent Gateway is a route-level filter that allows you to control the traffic flow on a specific route. It supports two fencing scopes:

  • ALL: Blocks all requests on the specified route. This is useful for scenarios such as maintenance windows or when you want to temporarily disable access to a route.

  • NONE: Allows all requests on the specified route.

gateway:
  routes:
    - name:
      fence:
        scope:          --- [1]
        errorCode:      --- [2]
        errorMessage:   --- [3]
  • [1] The fencing scope of the filter. The default value is NONE. Set to ALL to block all requests on the route.

  • [2] Optional. The error code to return for blocked requests. The default value is BROKER_NOT_AVAILABLE.

    For a list of valid error codes, see Kafka protocol error codes.

  • [3] Optional. The error message to return for blocked requests. The default value is This route is currently unavailable - all requests are blocked.

The following is an example configuration for a Confluent Gateway route with the fencing filter enabled:

gateway:
  routes:
    - name: eu-sales
      endpoint: eu-gw.sales.example.com:9092
      fence:
        scope: ALL
        errorCode: BROKER_NOT_AVAILABLE
        errorMessage: "Maintenance in progress - route temporarily unavailable"
      brokerIdentificationStrategy:
        type: host
        pattern: broker-$(nodeId).eu-gw.sales.example.com:9092
      streamingDomain:
        name: sales
        bootstrapServerId: SASL_SSL-1

Administration and metrics configuration

gateway:
  admin:
    bindAddress:             --- [1]
    port:                    --- [2]
    endpoints:
      metrics:               --- [3]
    jvmMetrics:              --- [4]
      - JvmGcMetrics
      - JvmMemoryMetrics
      - JvmThreadMetrics
      - ProcessorMetrics
      - UptimeMetrics
    commonTags:              --- [5]
      host:
      region:
  • [1] The local address to bind admin service and to listen on for incoming connections. The default value is 0.0.0.0.

    This address determines which network interfaces the gateway will use to expose its administrative endpoints, such as metrics and liveness checks.

  • [2] The TCP port for exposing admin endpoints. The default value is 9190.

    The Confluent Gateway will serve metrics at http://{bindAddress}:{port}/metrics and liveness check at http://{bindAddress}:{port}/livez.

  • [3] The metrics endpoints to be enabled and exposed. The default value is true.

  • [4] The standard JVM Metrics (uses Micrometer classes). By default JvmGcMetrics, JvmMemoryMetrics, JvmThreadMetrics, ProcessorMetrics, UptimeMetrics are enabled.

  • [5] Optional. The common tags to be applied to all the metrics.

An example configuration for a Confluent Gateway Admin and Metrics:

admin:
  bindAddress: 0.0.0.0
  port: 9190
  endpoints:
    metrics: true
  jvmMetrics:
    - JvmGcMetrics
    - JvmMemoryMetrics
    - JvmThreadMetrics
    - ProcessorMetrics
    - UptimeMetrics
  commonTags:
    host: pod-0
    region: us-west-2

License configuration

The table below summarizes the license modes supported by Confluent Gateway.

Deployment mode

Trial mode (default)

Enterprise mode for Confluent Private Cloud deployments

License required

No license is required

Valid Confluent Private Cloud Gateway license key(s)

Limitation

Maximum of 4 routes can be configured

Supports only Confluent Private Cloud streaming domains

Purpose

Evaluation and testing

Gateway forwarding to self-managed Kafka clusters

Duration

N/A

As specified in the license claim

Image

Use confluentinc/cpc-gateway

Use confluentinc/cpc-gateway

To configure the Enterprise license mode:

  1. Contact Confluent to get one or more valid license keys for production use.

  2. Configure the GATEWAY_LICENSES environment variable using the license key you obtained in the previous step.

    • Option A: Set the environment variable before starting the Confluent Gateway.

      export GATEWAY_LICENSES="your-license-key"
      

      To add multiple license keys, use the following syntax using the dollar sign ($) to escape the newline character (\n).

      export GATEWAY_LICENSES=$'your-first-license-key\nyour-second-license-key'
      
    • Option B: Edit docker-compose.yaml. You can add multiple license keys, one per line.

      gateway:
        environment:
          GATEWAY_LICENSES: |
            your-first-license-key
            your-second-license-key
      
  3. To verify the license status, check the Confluent Gateway logs for license information after starting the Confluent Gateway.

    docker logs gateway | grep -i license
    

For example license configurations, see Confluent Gateway examples in GitHub.

Install Confluent Gateway using Docker

Deploy Confluent Gateway using the configuration file (docker-compose.yaml by default) you set up in the previous section, Configure Confluent Gateway using Docker Compose.

docker compose -f docker-compose.yaml up -d

Troubleshoot Confluent Gateway

Use this section to collect diagnostics and resolve common issues when running Confluent Gateway with Docker.

Capture Confluent Gateway logs manually

Use Docker commands to inspect the Confluent Gateway container logs.

# View all Gateway logs
docker logs gateway

# Filter for errors
docker logs gateway | grep -i error

# Filter for license-related messages
docker logs gateway | grep -i license

Begin troubleshooting by inspecting the Confluent Gateway container logs. Most initialization failures, including network timeouts and credential errors, are captured here.

Enable debug logging to view stack traces

Set the global Confluent Gateway log level to DEBUG to capture detailed logs, including stack traces. This helps diagnose complex issues when running Confluent Gateway.

Update your docker-compose.yaml file to include the GATEWAY_ROOT_LOG_LEVEL environment variable:

gateway:
  environment:
    GATEWAY_ROOT_LOG_LEVEL: "DEBUG"

The GATEWAY_ROOT_LOG_LEVEL environment variable controls the global logging level for Confluent Gateway, and the DEBUG log level captures detailed system events, including stack traces.

Known and common issues

Confluent Gateway container exits or restarts repeatedly

Symptoms

  • The Confluent Gateway container terminates after startup.

  • Running the docker ps command shows the container is repeatedly restarting.

  • Running the docker compose up command shows that the service failed to start.

  • Logs contain configuration parsing errors, license validation failures, or stack traces.

Likely causes

  • Invalid or incomplete Confluent Gateway configuration file.

  • Misconfigured environment variables in the docker-compose.yaml file.

Resolution

  1. Inspect the logs for configuration and license errors: Identify messages indicating failed YAML parsing, unknown fields, or unrecognized license keys.

    docker logs gateway
    docker logs gateway | grep -i license
    
  2. Verify configuration file mapping: Confirm that the volumes section in your docker-compose.yaml file correctly maps the local configuration file to the expected path in the container.

  3. Validate the configuration file structure:

    • Ensure that the streamingDomains section defines at least one streaming domain and a corresponding bootstrap server.

    • Ensure that the routes section defines at least one valid route definition.

  4. Validate enterprise mode configuration: If you are using the enterprise license, confirm that the GATEWAY_LICENSES environment variable contains valid and unexpired license keys.

Clients can’t connect to the Confluent Gateway endpoint

Symptoms

  • Clients connections to the Confluent Gateway endpoint either time out or stall indefinitely during metadata requests.

  • Clients can directly connect to the Kafka cluster, but connections fail when routed through the Confluent Gateway.

Likely causes

  • The Confluent Gateway container can’t reach the Kafka bootstrap servers due to DNS, firewall, or network issues.

  • Clients are incorrectly configured to connect to broker addresses directly instead of the Confluent Gateway route endpoint.

  • The routes.endpoint value doesn’t match the host and port published by the Docker container.

  • The bootstrapServerId is mismatched across different sections of the configuration.

Resolution

  1. Confirm Docker port mappings: If the Confluent Gateway route endpoint is defined as gateway.example.com:19092, ensure that your docker-compose.yaml file publishes to that port. For example:

    gateway:
      ports:
        - "19092:19092"
    
  2. Test Gateway to Kafka connectivity:

    • From within the container network or host where Confluent Gateway runs, test connectivity to the Kafka bootstrap endpoints defined under streamingDomains.kafkaCluster.bootstrapServers[].endpoint.

    • Inspect DNS resolution, firewall rules, and network routing.

  3. Review logs for authentication issues: Inspect logs for repeated connection attempts or terminated during authentication messages. If these errors occur, verify your authentication and SSL/TLS configuration settings.

  4. Verify Broker Endpoint Resolution:

    When using the host-based brokerIdentification strategy, clients must resolve individual broker addresses to the Confluent Gateway’s network load balancer (NLB). If your broker address pattern is defined as b$(nodeId).gateway.example.com, ensure that your DNS provider is configured to route these subdomains correctly.

    Required DNS Configuration:

    To support dynamic broker identification, you must configure a wildcard DNS record pointing to your Confluent Gateway NLB:

    Record Type

    Host / Pattern

    Target

    A

    gateway.example.com

    <gateway-nlb-host>

    A (Wildcard)

    *.gateway.example.com

    <gateway-nlb-host>

    Common Misconfigurations to Avoid:

    Avoid the following settings, which will prevent clients from connecting to the brokers:

    • Invalid Endpoint Binding: route.endpoint = 0.0.0.0

      Result: The Confluent Gateway will advertise broker endpoints as localhost or 0.0.0.0 to the client. The client will attempt to connect to its own local machine instead of the Confluent Gateway.

    • Unresolvable Host Patterns: route.brokerIdentification.pattern = b$(nodeId).<unresolvable-host>

      Result: While the Confluent Gateway may start successfully, clients will encounter UnknownHostException because the generated broker addresses don’t exist in your DNS registry.

    • Missing Wildcard Records: If you only map the root domain (gateway.example.com) without the wildcard (*), individual broker lookups like b0.gateway.example.com will fail.

Protocol or SSL/TLS mismatch

Symptoms

  • Client logs or Confluent Gateway logs show errors such as frame size exceptions or TLS handshake failures.

  • Clients use SASL_SSL or SSL but the route is configured as plaintext, or vice versa.

Likely causes

  • The client’s security.protocol doesn’t match the configured security for the route.

  • TLS-encrypted traffic is directed to a plaintext route endpoint, or plaintext traffic is directed to an SSL-only route.

Resolution

  1. Confirm route configuration and restart the Confluent Gateway service to verify that client connectivity is restored.

    • Inspect the gateway.routes[].security.ssl settings in the Confluent Gateway configuration file.

    • If security.ssl is omitted, the route expects plaintext traffic.

    • If security.ssl is defined, configure the client to use an SSL protocol, such as, SASL_SSL or SSL.

  2. Align client configuration:

    • For unencrypted connections, set the client protocol to PLAINTEXT.

    • When using SASL authentication without TLS, set the client protocol to SASL_PLAINTEXT.

    • For TLS routing, set the client protocol to SSL or SASL_SSL and configure the truststore and keystore as required.

Authentication swap not behaving as expected

Symptoms

  • Clients using authentication swap fail to authenticate with the backend cluster.

  • Logs report errors related to secret store lookups, JAAS configuration failures, or callback handler initialization.

  • Backend brokers report invalid credentials despite the client providing valid local certificates.

Likely causes

  • Route security isn’t configured with auth: swap.

  • The secretStore name referenced in the Confluent Gateway configuration is incorrect or missing in the routes section.

  • Secret store provider type is incorrect, or the credentials required to access the store are misconfigured.

Resolution

  1. Verify route swap configuration: Ensure the defined routes perform authentication swapping.

    gateway:
      routes:
        - name: <route-name>
          security:
            auth: swap
            swapConfig: <swap-config>
    
  2. Avoid hardcoded broker credentials for cluster authentication: Don’t embed static broker credentials in the Confluent Gateway configuration. For swap scenarios, credentials must be dynamically resolved from a supported provider such as, HashiCorp Vault, or a local file, or other supported secret stores for dynamic resolution.

  3. Validate your secret store configuration:

    • Provider types are case-sensitive. Verify that you are using the exact casing required. For example, use Azure, not AZURE.

    • Confirm the Confluent Gateway has the necessary permissions to read secrets from the provider.

    • Ensure the Confluent Gateway can reach the secret store’s API endpoint over the network.

OAuth token endpoint not allowed

Symptoms

The Confluent Gateway fails to fetch OAuth tokens, and logs report a security restriction similar to: ... is not allowed. Update system property 'org.apache.kafka.sasl.oauthbearer.allowed.urls'to allow https://...

Likely causes

For security purposes, the Confluent Gateway requires an allowlist of outbound OAuth token requests. The configured OAuth token URL used by the identity provider isn’t included in the default allowlist.

Resolution

  1. Add the OAuth token endpoint to the GATEWAY_OPTS environment variable in the docker-compose.yaml file:

    gateway:
      environment:
        GATEWAY_OPTS:
          -Dorg.apache.kafka.sasl.oauthbearer.allowed.urls=
          https://login.microsoftonline.com/<tenantId>/oauth2/v2.0/token
    
  2. Restart the Confluent Gateway service to apply the configuration changes. Check the logs to ensure the not allowed error no longer appears during the authentication handshake.

License and route limit issues

Symptoms

  • The Confluent Gateway fails to initialize additional routes.

  • Logs report warnings on license or route-limit exhaustion.

Likely causes

The Confluent Gateway is running in trial mode, which has a maximum limit of four routes. To configure more routes, an enterprise license is required.

Resolution

  1. Understand license modes:

    • Trial mode (Default): Requires no license key. It is strictly limited to four routes.

    • Enterprise mode: Requires a valid Confluent Private Cloud license to support unlimited routes.

  2. Apply an enterprise license: To enable more than four routes, add your license key to the GATEWAY_LICENSES environment variable in your docker-compose.yaml file.

  3. Inspect the license status: After restarting the service, verify that the Confluent Gateway has successfully recognized the license. Run docker logs gateway | grep -i license to confirm the license status.