Swill
← Back

GKE Private Service Connect for Strimzi Kafka

·Updated April 10, 2026·2 min read·

Configure Service Attach

apiVersion: networking.gke.io/v1
kind: ServiceAttachment
metadata:
  name: kafka-cluster-psc-broker-0
  namespace: kafka
spec:
  connectionPreference: ACCEPT_MANUAL
  consumerAllowList:
    - connectionLimit: 5
      ## automatically accept connection
      project: {project id}
  # subnets is only for this Service Attach, can not share with different Service Attach.
  natSubnets:
    - >-
      projects/{project/regions/asia-southeast1/subnetworks/{subset-name}
  proxyProtocol: false
  resourceRef:
    kind: Service
    name: {kubernetes service name}
  • consumerAllowList: allows automatic connection with defined project
  • natSubnets: cannot share with different Service Attach
  • proxyProtocol: use false for Kafka — when true, PSC adds proxy protocol bytes that break the Kafka/SASL stream:
2025-09-23 08:48:53,080 INFO [SocketServer listenerType=ZK_BROKER, nodeId=0] Failed authentication with /10.167.48.23 (channelId=10.167.2.223:9097-10.167.48.23:56462-13) (Failing SASL authentication due to invalid receive size) (org.apache.kafka.common.network.Selector) [data-plane-kafka-network-thread-0-ListenerName(EXTERNALPSC-9097)-SASL_PLAINTEXT-21]

Configure Listeners

listeners:
  - authentication:
      type: scram-sha-512
    configuration:
      bootstrap:
        annotations:
          cloud.google.com/load-balancer-type: Internal
          networking.gke.io/internal-load-balancer-allow-global-access: "true"
      brokers:
        - advertisedHost: {Use psc IP}
          annotations:
            cloud.google.com/load-balancer-type: Internal
            networking.gke.io/internal-load-balancer-allow-global-access: "true"
          broker: 0
        - advertisedHost: {Use psc IP}
          annotations:
            cloud.google.com/load-balancer-type: Internal
            networking.gke.io/internal-load-balancer-allow-global-access: "true"
          broker: 1
        - advertisedHost: {Use psc IP}
          annotations:
            cloud.google.com/load-balancer-type: Internal
            networking.gke.io/internal-load-balancer-allow-global-access: "true"
          broker: 2
    name: externalpsc
    port: 9097
    tls: false
    type: loadbalancer

Root cause (proxy protocol vs SASL)

A conflict between the proxy protocol and SASL often appears when a load balancer or proxy prepends the proxy protocol header while the application expects a plain TLS ClientHello or another framing. Proxy protocol bytes at the start of the stream interfere with SASL framing and handshakes, which leads to failures such as invalid receive size during authentication.