lemon-king-63400
03/05/2026, 10:07 AMtall-airline-16756
03/05/2026, 10:07 AMtall-airline-16756
03/05/2026, 10:08 AMrequest has missing or invalid field: token or api key/secret and the egress JSON showing egress_id: null and filepath: null.
Quick checklist (do these in order):
1) Ensure Egress has API credentials
• Add the API key and secret as environment variables in the Egress container:
◦ LIVEKIT_API_KEY = your-api-key
◦ LIVEKIT_API_SECRET = your-api-secret
◦ LIVEKIT_URL = the LiveKit server URL (example: ws://livekit:7880 or your external URL)
• Restart the Egress pod after adding/updating these values so they are picked up.
2) Confirm values are correct and not mistyped
• Double-check there are no extra quotes, hidden characters, or typos in the key/secret names or values.
• If you rotate keys, make sure Egress uses the current secret.
3) If you use JWT token auth for egress instead of API key/secret
• Verify the token is signed with the correct API secret.
• Ensure the token includes necessary permissions for recording (room recording/egress).
• Check exp and nbf are valid and the token is not expired/not-yet-valid.
• Decode the token (e.g., via jwt.io or echo "<token>" | cut -d'.' -f2 | base64 -d | jq) to inspect claims.
4) Verify Egress can reach the LiveKit server
• Exec into any pod (or use a test pod) and curl the LiveKit URL to confirm connectivity:
◦ curl -v http://livekit:7880
• Ensure the Twirp endpoints are reachable from the Egress pod.
5) If you’re using SIP Dispatch Rules / auto-egress
• Ensure your dispatch rule includes room_config.egress (so rooms created by SIP have egress recording configured).
• Example: room_config with egress outputs (S3, file, etc.) must be present for auto-egress to start recordings.
6) Inspect logs after changes
• Restart Egress and check logs:
◦ kubectl logs -f <egress-pod-name>
• Successful auth will remove the Twirp invalid_argument error; otherwise logs will show further clues.
What success looks like
• Egress logs show a successful initialization/auth handshake.
• When a call starts, the room’s egress fields populate with egress_id and filepath instead of null.
If you want, tell me:
• How you currently provide credentials to the Egress pod (env vars, secret mount, or token).
• The LiveKit service URL you set in the Egress deployment (cluster-internal or external).
• Whether you use API key/secret or JWT tokens for Egress auth.
With that I can give the exact Kubernetes YAML snippet or token validation steps to apply to your deployment.
Sources: Server-side | livekit/livekit_composite | DeepWiki | server-sdk-js | livekit/livekit_composite | DeepWiki | sip | livekit/livekit_composite | DeepWiki | Troubleshooting 401 Unauthorized and Token Errors | LiveKit | Universal Egresslemon-king-63400
03/05/2026, 10:26 AMtall-airline-16756
03/05/2026, 10:26 AMapiVersion: v1
kind: Secret
metadata:
name: livekit-secrets
namespace: livekit
type: Opaque
data:
api-key: BASE64_ENCODED_API_KEY
api-secret: BASE64_ENCODED_API_SECRET
2) Deployment for LiveKit Egress
apiVersion: apps/v1
kind: Deployment
metadata:
name: livekit-egress
namespace: livekit
labels:
app: livekit-egress
spec:
replicas: 1
selector:
matchLabels:
app: livekit-egress
template:
metadata:
labels:
app: livekit-egress
spec:
containers:
- name: egress
image: livekit/egress:latest
ports:
- containerPort: 7980
name: http
env:
- name: LIVEKIT_URL
value: "<wss://your-livekit-domain.com>" # or ws:// for internal cluster URL
- name: LIVEKIT_API_KEY
valueFrom:
secretKeyRef:
name: livekit-secrets
key: api-key
- name: LIVEKIT_API_SECRET
valueFrom:
secretKeyRef:
name: livekit-secrets
key: api-secret
- name: REDIS_URI
value: "<redis://redis.livekit.svc.cluster.local:6379>" # update as needed
- name: GST_DEBUG
value: "3" # optional for debugging gstreamer
- name: LIVEKIT_REGION
value: "us-west" # optional
readinessProbe:
httpGet:
path: /health
port: 7980
initialDelaySeconds: 10
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 7980
initialDelaySeconds: 30
periodSeconds: 10
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2"
memory: "2Gi"
3) Cluster Service (optional — for internal access / health checks)
apiVersion: v1
kind: Service
metadata:
name: livekit-egress
namespace: livekit
labels:
app: livekit-egress
spec:
selector:
app: livekit-egress
ports:
- protocol: TCP
port: 7980
targetPort: http
name: http
Notes and quick checks
• LIVEKIT_URL must point to your LiveKit server (internal cluster address or public WSS). Egress must be able to reach this URL.
• LIVEKIT_API_KEY and LIVEKIT_API_SECRET must be correct and accessible by the Egress pod — incorrect/missing credentials cause the Twirp invalid_argument error you saw.
• REDIS_URI: Egress uses Redis to receive job requests; confirm Redis is reachable from the pod.
• Restart the Deployment after you create/update the Secret so the pod picks up new values: kubectl rollout restart deployment/livekit-egress -n livekit
• Monitor logs for auth success or remaining errors: kubectl logs -f deploy/livekit-egress -n livekit
If you’d like, I can:
• Provide a variant that uses a mounted file Secret instead of env vars.
• Show the exact kubectl commands to create the Secret (including base64 encode commands).
• Tailor resource requests/limits and replica count for production load.
Which of those would help you next?
Sources: Universal Egress | Universal Egress | livekit/livekit_composite | DeepWiki | sip | livekit/livekit_composite | DeepWiki | Backup Egress Recordings