Hi ai, TURNS Connection Issues with GKE LoadBalanc...
# ask-ai
b
Hi ai, # TURNS Connection Issues with GKE LoadBalancer - Error 701 ## Problem Description Some ios user using wifi can not join. I'm experiencing TURNS (TLS over TCP) connection issues in my GKE deployment. TURN UDP works perfectly, but TURNS consistently fails with error code 701. The connection shows "Address not associated with the desired network interface" errors. ## Error Logs
Copy code
Establishing WebRTC connection

udp 34.154.109.20:56200 host

tcp 34.154.109.20:7881 host (passive)

udp 169.254.123.1:57956 host

tcp 169.254.123.1:7881 host (passive)

Warning: error with ICE candidate: 701 Address not associated with the desired network interface. turns:turndomain:443?transport=tcp

Warning: error with ICE candidate: 701 Address not associated with the desired network interface. turns:turndomain:443?transport=tcp

Warning: error with ICE candidate: 701 Address not associated with the desired network interface. turns:turndomain:443?transport=tcp

Warning: error with ICE candidate: 701 Address not associated with the desired network interface. turns:turndomain:443?transport=tcp

Warning: error with ICE candidate: 701 Address not associated with the desired network interface. turns:turndomain:443?transport=tcp
## Current Configuration ### LiveKit Secret (livekit.yaml)
Copy code
yaml
apiVersion: v1
kind: Secret
metadata:
  name: livekit-secret
  namespace: livekit
type: Opaque
stringData:
  livekit.yaml: |
    port: 7880
    rtc:
      tcp_port: 7881
      use_external_ip: true
      enable_loopback_candidate: false
      port_range_start: 50000
      port_range_end: 60000
    redis:
      address: redis:6379
      db: 0
    turn:
      enabled: true
      domain: turndomain
      udp_port: 3478
      tls_port: 5349
      external_tls: false  # ← IS THIS THE ISSUE?
      cert_file: /etc/livekit/tls/tls.crt
      key_file: /etc/livekit/tls/tls.key
    keys:
      key: secret
    webhook:
      api_key: key
      urls:
        - webhook
    room:
      auto_create: false
      max_participants: 1000
      enable_remote_unmute: false
    prometheus_port: 6789
    development: false
    logging:
      level: debug
### LiveKit Deployment
Copy code
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: livekit-server
  namespace: livekit
spec:
  replicas: 3
  selector:
    matchLabels:
      app: livekit-server
  template:
    metadata:
      labels:
        app: livekit-server
    spec:
      terminationGracePeriodSeconds: 90
      hostNetwork: true  _# ← POTENTIAL ISSUE?_
      dnsPolicy: ClusterFirstWithHostNet
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - livekit-server
            topologyKey: "<http://kubernetes.io/hostname|kubernetes.io/hostname>"
      nodeSelector:
        <http://kubernetes.io/os|kubernetes.io/os>: linux
        <http://cloud.google.com/gke-nodepool|cloud.google.com/gke-nodepool>: high-performance-pool
      containers:
      - name: livekit-server
        image: livekit/livekit-server:v1.9.1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 7880
          name: http
        - containerPort: 7881
          name: rtc-tcp
        - containerPort: 3478
          protocol: UDP
          name: turn-udp
        - containerPort: 3478
          protocol: TCP
          name: turn-tcp
        - containerPort: 5349
          protocol: TCP
          name: turn-tls
        env:
        - name: LIVEKIT_CONFIG
          valueFrom:
            secretKeyRef:
              name: livekit-secret
              key: livekit.yaml
        - name: LIVEKIT_RTC_PORT_RANGE_START
          value: "50000"
        - name: LIVEKIT_RTC_PORT_RANGE_END
          value: "60000"
        - name: LIVEKIT_ICE_CANDIDATE_TIMEOUT
          value: "15s"
        - name: LIVEKIT_ICE_CONNECTION_TIMEOUT
          value: "30s"
        - name: LIVEKIT_NODE_ID
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        livenessProbe:
          httpGet:
            path: /
            port: 7880
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /
            port: 7880
          initialDelaySeconds: 10
          periodSeconds: 5
        resources:
          requests:
            cpu: 2200m
            memory: 8Gi
          limits:
            memory: 10Gi
            cpu: 2600m
        volumeMounts:
        - name: tls-volume
          mountPath: /etc/livekit/tls
          readOnly: true
      volumes:
      - name: tls-volume
        secret:
          secretName: media-app-tls
### TURN Services
Copy code
yaml
_# TCP/TLS (443 external → 5349 internal)_
apiVersion: v1
kind: Service
metadata:
  name: turn-tcp
  namespace: livekit
  annotations:
    <http://cloud.google.com/load-balancer-type|cloud.google.com/load-balancer-type>: "External"
spec:
  type: LoadBalancer
  loadBalancerIP: 34.102.94.232
  selector:
    app: livekit-server
  ports:
    - name: turns
      port: 443
      targetPort: 5349
      protocol: TCP
---
_# UDP 3478 (working fine)_
apiVersion: v1
kind: Service
metadata:
  name: turn-udp
  namespace: livekit
  annotations:
    <http://cloud.google.com/load-balancer-type|cloud.google.com/load-balancer-type>: "External"
spec:
  type: LoadBalancer
  loadBalancerIP: 34.102.94.232
  selector:
    app: livekit-server
  ports:
    - name: turn-udp
      port: 3478
      targetPort: 3478
      protocol: UDP
### Main Ingress
Copy code
yaml
apiVersion: <http://networking.k8s.io/v1|networking.k8s.io/v1>
kind: Ingress
metadata:
  name: livekit-ingress-controller
  namespace: livekit
  annotations:
    <http://kubernetes.io/ingress.class|kubernetes.io/ingress.class>: "gce"
    <http://kubernetes.io/ingress.global-static-ip-name|kubernetes.io/ingress.global-static-ip-name>: "livekit-ip"
    <http://kubernetes.io/ingress.allow-http|kubernetes.io/ingress.allow-http>: "true"
    <http://cloud.google.com/armor-config|cloud.google.com/armor-config>: '{"rule": "livekit-cloud-armor-policy"}'
    <http://networking.gke.io/managed-certificates|networking.gke.io/managed-certificates>: "livekit-certificate"
    <http://nginx.ingress.kubernetes.io/proxy-read-timeout|nginx.ingress.kubernetes.io/proxy-read-timeout>: "7200"
    <http://nginx.ingress.kubernetes.io/proxy-send-timeout|nginx.ingress.kubernetes.io/proxy-send-timeout>: "7200"
    <http://cloud.google.com/backend-timeout-sec|cloud.google.com/backend-timeout-sec>: "7200"
spec:
  rules:
  - host: ingress-domain
    http:
      paths:
      - path: /*
        pathType: ImplementationSpecific
        backend:
          service:
            name: livekit-ingress
            port:
              number: 80
  - host: lk domain
    http:
      paths:
      - path: /*
        pathType: ImplementationSpecific
        backend:
          service:
            name: livekit-server
            port:
              number: 80
## Observations 1. TURN UDP works perfectly:
turn:34.14.109.20:3478?transport=udp
succeeds 2. TURNS TCP fails:
turns:turndomain:443?transport=tcp
fails with error 701 4. Network interface issue: Error suggests address not associated with desired network interface ## Specific Questions 1. Should
external_tls
be
true
when using GKE LoadBalancer with 443→5349 port mapping? 2. Is
hostNetwork: true
causing the issue?
Could this be creating network interface conflicts in GKE? 3. TLS Termination: Should TLS be terminated at: - LoadBalancer level (external_tls: true) - LiveKit level (external_tls: false) 4. IP Address inconsistency: Why are different IPs showing up in error logs vs service configuration? 5. GKE-specific configuration: Are there any special considerations for TURNS in GKE that I'm missing? ## Environment Details - Platform: Google Kubernetes Engine (GKE) - LiveKit Server: v1.9.1 - Node Pool: high-performance-pool - Status: - TURN UDP: ✅ Working - TURNS TCP: ❌ Failing with error 701 - WebRTC Connection: Eventually succeeds despite TURNS errors ## Expected Behavior TURNS should work over TCP port 443 with TLS, allowing clients behind restrictive firewalls to connect. ## What I've Tried - Verified TLS certificates are properly mounted - Confirmed LoadBalancer services are running - Checked that ports 443 and 5349 are open - Verified domain
turndomain
resolves correctly Any insights on what might be causing this TURNS configuration issue would be greatly appreciated!
t
Thanks for reaching out, Enes. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
To help us get to the bottom of the TURNS connection issue together, could you please check a few things for me? • Does the result of
dig turndomain
match the external IP of your GKE load balancer? • Is the
use_external_ip: true
setting enabled in your configuration? • Is your GKE cluster VPC-native or using NAT64, and is ExternalDNS handling the DNS records? Understanding these details will really help us figure out whether the issue is with IP resolution, DNS, or how the service is exposed. Thanks so much for your help with this! Sources: livekit-server/templates/turnloadbalancer.yaml | Deploy to a VM | LiveKit Docs | Deploying LiveKit | LiveKit Docs | Diagnosing Connection Errors with Connection Test Utility | docs/tutorials/gke-nginx.md
b
yes match my turn domain.when using use_external_ip: true ı saw log ip not validating I am using vpc native
t
To help resolve the TURNS connection issue you're experiencing, could you please check a couple of things for me? • Have you set
turn.tls_port
to 443 in your LiveKit configuration? • Are the GCP firewall rules allowing both UDP and TCP traffic on port 443? These settings are really important to make sure TURNS works smoothly in a VPC-native GKE cluster. Let me know what you find, and we’ll take it from there together! Sources: Deploying LiveKit | LiveKit Docs | livekit-server/templates/service.yaml | CHANGELOG.md | src/connectionHelper/checks/turn.ts | Firewall Tips
b
I set turn.tls_port 5349 bu my lb 443 to 5349
t
I don't have the answer you're looking for. You could also try asking your question: • in one of the other Slack channels or • to https://deepwiki.com/livekit/livekit_composite which is trained on all LiveKit source code If you find the answer, please post it here to help others!