magnificent-monitor-48407
12/27/2025, 6:07 AMtall-airline-16756
12/27/2025, 6:07 AMtall-airline-16756
12/27/2025, 6:07 AMSYS_ADMIN)?
If you prefer, paste the relevant section of your values.yaml (egress container args/env and securityContext) and I’ll suggest the exact Helm values to change.magnificent-monitor-48407
12/27/2025, 12:41 PMtall-airline-16756
12/27/2025, 12:41 PMegress block):
egress:
containers:
egress:
securityContext:
privileged: true
After updating values.yaml, deploy the chart (example):
1. helm upgrade --install livekit ./charts/livekit -f values.yaml
2. kubectl rollout status deployment/livekit-egress
Notes and checks:
• Privileged containers grant broad rights. Confirm your cluster/security policy allows privileged pods.
• If privileged is not allowed, an alternative is to enable user namespaces on the host kernel (recommended for least privilege) so Chrome can use its user sandbox instead of requiring privileged mode.
• If you’re unsure whether privileged pods are permitted, tell me your cluster type (EKS/GKE/AKS/self-managed) and I’ll suggest cluster-specific steps or a non-privileged alternative. Sources: Server-side | livekit/livekit_composite | DeepWikimagnificent-monitor-48407
12/27/2025, 12:50 PMtall-airline-16756
12/27/2025, 12:51 PMkubectl logs livekit-egress-sandbox-6d674f9bff-cspz8 --all-containers --timestamps
▪︎ If the pod restarts, include previous logs: add --previous.
1. Pod description and events:
◦ kubectl describe pod livekit-egress-sandbox-6d674f9bff-cspz8
1. The egress container security/privileges from your values.yaml (or what you applied):
◦ The egress.containers.egress.securityContext block you used.
1. The egress command/args or recording target (if customized):
◦ Any args, env, or command overrides for the egress container.
If you prefer, paste the relevant excerpts (logs + describe + securityContext) and I’ll analyze them and give exact changes or fixes.magnificent-monitor-48407
12/27/2025, 12:51 PMtall-airline-16756
12/27/2025, 12:51 PMsandbox: false, insecure: true in the launch info.
• GStreamer starts audio pipeline work, then the code logs chrome: END_RECORDING almost immediately and sends EOS, which closes the pipeline and aborts the egress.
• There are warnings about missing libcuda.so.1 (video hardware accel; not fatal for audio).
• The rapid END_RECORDING indicates Chrome (or the headless page it loads) is exiting or failing to start a working media session.
Next steps to troubleshoot and fix
1. Confirm securityContext you applied
◦ Show me the egress.containers.egress.securityContext from your values.yaml (or confirm if you set privileged: true). If not set, Chrome’s sandbox may be failing and the egress may be forcing end of recording.
1. Check container stdout for Chrome/renderer errors
◦ Run: kubectl logs livekit-egress-sandbox-6d674f9bff-cspz8 --container egress --timestamps
◦ Look for Chrome-specific errors (renderer crash, missing sandbox files, or permission errors). Paste any lines that mention "crash", "sandbox", "render", or "DevTools listening".
1. If privileged is not enabled
◦ Set privileged true in values.yaml:
egress:
containers:
egress:
securityContext:
privileged: true
• Re-deploy the chart and try again. Privileged resolves Chrome sandbox issues when user namespaces are not enabled.
1. If you cannot use privileged pods
◦ Two alternatives:
▪︎ Enable user namespaces (userns) on host kernel so Chrome can use user sandbox (recommended least-privilege).
▪︎ Launch Chrome with no-sandbox flags (less secure). If you want this quick workaround, tell me and I’ll provide the exact values.yaml snippet that sets the egress container args to include --no-sandbox --disable-setuid-sandbox.
1. Check the page URL/connectivity the egress loads
◦ The log shows it loads a local URL with a token. Confirm the internal web server at port 7980 is healthy and serving the expected page. From inside the pod you can curl that URL to confirm it returns HTML: kubectl exec -it pod -- curl -sS <http://localhost:7980/>
1. Share any Chrome error lines
◦ If you paste Chrome-specific stderr lines from the logs I’ll pinpoint whether it’s a sandbox permission error, an immediate page failure, or a networking/auth token issue.
What I recommend now
• First, confirm whether you set privileged: true. If not, try enabling it and redeploy. If you can’t, paste the egress container logs (full Chrome stderr lines) and I’ll give the exact values.yaml change for --no-sandbox or further diagnostics.
Tell me which option you want to try and paste the securityContext or Chrome error lines and I’ll provide the exact helm values and commands.magnificent-monitor-48407
12/27/2025, 12:56 PMtall-airline-16756
12/27/2025, 12:56 PMSYS_ADMIN added, not full privileged mode. That likely still prevents Chrome’s sandbox from working, which explains the immediate END_RECORDING.
Next steps (choose one):
1) Enable privileged mode (recommended when userns is off)
• Set this in your values.yaml:
egress:
containers:
egress:
securityContext:
privileged: true
• Then redeploy: helm upgrade --install livekit ./charts/livekit -f values.yaml
• Verify pod comes up and try the recording.
2) If you cannot use privileged pods, run Chrome without the sandbox (less secure)
• Add Chrome args to the egress container to disable sandbox:
egress:
containers:
egress:
args:
- "--no-sandbox"
- "--disable-setuid-sandbox"
• Redeploy and test.
3) Longer-term secure option
• Enable user namespaces on your hosts so Chrome can use its user sandbox (I can give host-specific steps if you tell me your cluster type: EKS/GKE/AKS/self-managed).
If you want, try option 1 first and paste the new pod logs if it still aborts. If you prefer option 2, tell me and I’ll provide the exact Helm snippet to merge into your chart (or the combined snippet that sets both privileged: true and the args).magnificent-monitor-48407
12/27/2025, 1:07 PM2025-12-27T13:06:31.246Z DEBUG egress server/main.go:177 handler launched {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632"}
2025-12-27T13:06:31.247Z INFO egress redis/redis.go:142 connecting to redis {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632", "simple": true, "addr": "livekit-redis-sandbox-redis-headless.default.svc.cluster.local:6379"}
2025-12-27T13:06:31.260Z DEBUG egress source/web.go:147 creating pulse sink {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632"}
2025-12-27T13:06:31.282Z DEBUG egress source/web.go:171 creating X display {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632", "display": ":1296087267", "dims": "1280x720x24"}
2025-12-27T13:06:31.283Z DEBUG egress source/web.go:202 launching chrome {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632", "url": "<http://localhost:7980/?layout=&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NjY5MjcxOTEsImlzcyI6IkFQSTI1NTEwZTI5ODJjMDMwZDciLCJraW5kIjoiZWdyZXNzIiwibmJmIjoxNzY2ODQwNzkxLCJzdWIiOiJFR19IdXg0dWJodko2MzIiLCJ2aWRlbyI6eyJjYW5QdWJsaXNoIjpmYWxzZSwiY2FuUHVibGlzaERhdGEiOmZhbHNlLCJjYW5TdWJzY3JpYmUiOnRydWUsImhpZGRlbiI6dHJ1ZSwicmVjb3JkZXIiOnRydWUsInJvb20iOiJkaXNwYXRjaC1hdWRpby1jYWxsLTU1MWUxYTAzLTYxYTgtNGJmNS1hYWZjLTlhNzdiYTk1MTRlNiIsInJvb21Kb2luIjp0cnVlfX0.Bcu0oKHuPSA2oWjMn3nvC69uGrRZCDa1YlwGjJvEnf8&url=ws%3A%2F%2Flivekit.default.svc.cluster.local%3A7880>", "sandbox": false, "insecure": true}
0:00:00.965413721 30 0x557bd038f040 WARN cudaloader gstcudaloader.c:169:gst_cuda_load_library: Could not open library libcuda.so.1, libcuda.so.1: cannot open shared object file: No such file or directory
0:00:00.965458192 30 0x557bd038f040 WARN nvcodec plugin.c:94:plugin_init: Failed to load cuda library
0:00:01.072865794 30 0x557bd038f040 WARN default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x120000: 'AVR (Audio Visual Research)' is not mapped
0:00:01.072921954 30 0x557bd038f040 WARN default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x180000: 'CAF (Apple Core Audio File)' is not mapped
0:00:01.072931075 30 0x557bd038f040 WARN default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x100000: 'HTK (HMM Tool Kit)' is not mapped
0:00:01.072945915 30 0x557bd038f040 WARN default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0xc0000: 'MAT4 (GNU Octave 2.0 / Matlab 4.2)' is not mapped
0:00:01.072953135 30 0x557bd038f040 WARN default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0xd0000: 'MAT5 (GNU Octave 2.1 / Matlab 5.0)' is not mapped
0:00:01.072960925 30 0x557bd038f040 WARN default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x210000: 'MPC (Akai MPC 2k)' is not mapped
0:00:01.073036956 30 0x557bd038f040 WARN default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x230000: 'MPEG-1/2 Audio' is not mapped
0:00:01.073047076 30 0x557bd038f040 WARN default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0xe0000: 'PVF (Portable Voice Format)' is not mapped
0:00:01.073062126 30 0x557bd038f040 WARN default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x160000: 'SD2 (Sound Designer II)' is not mapped
0:00:01.073072776 30 0x557bd038f040 WARN default gstsfelement.c:97:gst_sf_create_audio_template_caps: format 0x190000: 'WVE (Psion Series 3)' is not mapped
2025-12-27T13:06:33.897Z DEBUG egress uploader/s3.go:79 setting S3 config {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632", "maxRetries": 3, "maxDelay": "5s", "minDelay": "100ms"}
2025-12-27T13:06:33.928Z DEBUG egress gstreamer/bin.go:66 adding src audio to pipeline {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632"}
2025-12-27T13:06:33.930Z DEBUG egress gstreamer/bin.go:72 adding sink file to pipeline {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632"}
2025-12-27T13:06:33.937Z DEBUG egress pipeline/controller.go:214 waiting for start signal {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632"}
2025-12-27T13:06:33.978Z INFO egress source/web.go:283 chrome: END_RECORDING {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632"}
2025-12-27T13:06:33.980Z DEBUG egress pipeline/controller.go:386 sending EOS {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632"}
2025-12-27T13:06:33.982Z DEBUG egress gstreamer/state.go:75 pipeline state building -> stopping {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632"}
2025-12-27T13:06:33.982Z DEBUG egress gstreamer/state.go:75 pipeline state stopping -> finished {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632"}
2025-12-27T13:06:33.983Z DEBUG egress pipeline/controller.go:439 closing source {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632"}
2025-12-27T13:06:33.983Z DEBUG egress source/web.go:113 closing chrome {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632"}
2025-12-27T13:06:34.059Z DEBUG egress source/web.go:119 closing X display {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632"}
2025-12-27T13:06:34.072Z DEBUG egress source/web.go:126 unloading pulse module {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632"}
2025-12-27T13:06:34.087Z DEBUG egress sink/file.go:73 removing temporary directory {"nodeID": "NE_7prTTkP5gzkX", "handlerID": "EGH_PjX6y7onLrtH", "clusterID": "", "egressID": "EG_Hux4ubhvJ632", "path": "/home/egress/tmp/EG_Hux4ubhvJ632/"}
2025-12-27T13:06:34.096Z INFO egress service/io.go:75 egress updated {"nodeID": "NE_7prTTkP5gzkX", "clusterID": "", "egressID": "EG_Hux4ubhvJ632", "requestType": "room_composite", "outputType": "file", "status": "EGRESS_ABORTED"}tall-airline-16756
12/27/2025, 1:07 PM--no-sandbox but the egress still immediately logs chrome: END_RECORDING and aborts.
Quick next checks so I can pinpoint the failure:
1) Paste the egress container environment and args:
• Run and share output:
◦ kubectl get pod livekit-egress-sandbox-6d674f9bff-cspz8 -o jsonpath='{.spec.containers[0].env}'
◦ kubectl get pod livekit-egress-sandbox-6d674f9bff-cspz8 -o jsonpath='{.spec.containers[0].args}'
2) Fetch Chrome stdout/stderr lines after launch (they often show why the page closed):
• kubectl logs livekit-egress-sandbox-6d674f9bff-cspz8 --container egress --timestamps | sed -n '1,200p'
◦ If logs rotate/are truncated, include --previous.
3) Confirm Pulse/ALSA access inside the pod:
• Exec into the pod and check Pulse modules and devices:
◦ kubectl exec -it livekit-egress-sandbox-6d674f9bff-cspz8 -- ls -l /dev/snd || true
◦ kubectl exec -it livekit-egress-sandbox-6d674f9bff-cspz8 -- pactl list short modules || true
4) As a test, try privileged mode (if allowed) — this resolves many sandbox/audio permission issues:
• In values.yaml set:
egress:
containers:
egress:
securityContext:
privileged: true
Redeploy and retry; if you prefer I can supply the exact helm command snippets.
Tell me the outputs from steps 1–3 and whether you can enable privileged mode; I’ll analyze and give the exact fix.magnificent-monitor-48407
12/27/2025, 1:10 PMtall-airline-16756
12/27/2025, 1:10 PM--no-sandbox (values.yaml egress container block).
If you prefer, paste the ConfigMap and the first ~400 lines of the egress container logs and I’ll start analyzing immediately.
Sources: Examples | livekit/livekit_composite | DeepWiki | Universal Egress | Server-side | livekit/livekit_composite | DeepWikimagnificent-monitor-48407
12/27/2025, 1:12 PMapiVersion: v1
data:
config.yaml: |
api_key: [redacted]
api_secret: [redacted]
containers:
egress:
args:
- --no-sandbox
- --disable-setuid-sandbox
securityContext:
privileged: true
health_port: 8080
insecure: true
log_level: debug
prometheus_port: 9090
redis:
address: [redacted]
db: 0
password: [redacted]
username: default
s3:
access_key: [redacted]
bucket: [redacted]
secret: [redacted]
ws_url: [redacted]
kind: ConfigMap
metadata:
annotations:
<http://meta.helm.sh/release-name|meta.helm.sh/release-name>: livekit-egress-sandbox
<http://meta.helm.sh/release-namespace|meta.helm.sh/release-namespace>: default
creationTimestamp: "2025-12-23T06:22:16Z"
labels:
<http://app.kubernetes.io/managed-by|app.kubernetes.io/managed-by>: Helm
name: livekit-egress-sandbox
namespace: default
resourceVersion: "10008282"
uid: b0dca0f7-b154-4a5d-ba77-949131a94c78tall-airline-16756
12/27/2025, 1:13 PMprivileged: true are set). Good.
Next I’ll focus on confirming whether the page Chrome loads can connect and whether PulseAudio/audio devices are available. Please run these from your machine and paste the outputs:
1) Check the page HTML Chrome loads (redact token): kubectl exec -it livekit-egress-sandbox-75587cc5c5-sxxgr -- curl -sS "http://localhost:7980/?token=<redacted-token>" | head -n 60
2) Verify the egress pod can reach the LiveKit websocket (replace with your ws_url from the ConfigMap, redact secrets): kubectl exec -it livekit-egress-sandbox-75587cc5c5-sxxgr -- curl -v "<ws_url>"
3) Confirm Pulse/ALSA devices and Pulse modules: kubectl exec -it livekit-egress-sandbox-75587cc5c5-sxxgr -- ls -l /dev/snd || true kubectl exec -it livekit-egress-sandbox-75587cc5c5-sxxgr -- pactl list short modules || true kubectl exec -it livekit-egress-sandbox-75587cc5c5-sxxgr -- pactl list short sinks || true
4) Full egress container logs (300–500 lines) in case Chrome stderr appears later: kubectl logs livekit-egress-sandbox-75587cc5c5-sxxgr --container egress --timestamps | sed -n '1,500p'
Also confirm: is there an active audio publisher in the room when you start egress? (yes/no)
Send those outputs and I’ll analyze them and give the exact next fix.magnificent-monitor-48407
12/27/2025, 1:15 PMtall-airline-16756
12/27/2025, 1:15 PMmagnificent-monitor-48407
12/27/2025, 1:16 PMegress@livekit-egress-sandbox-75587cc5c5-sxxgr:/$ ls -l /dev/snd || true
ls: cannot access '/dev/snd': No such file or directory
egress@livekit-egress-sandbox-75587cc5c5-sxxgr:/$ pactl list short modules || true
0 module-device-restore
1 module-stream-restore
2 module-card-restore
3 module-augment-properties
4 module-switch-on-port-available
5 module-switch-on-connect
6 module-udev-detect
7 module-native-protocol-unix
8 module-default-device-restore
9 module-always-sink
11 module-intended-roles
12 module-suspend-on-idle
13 module-systemd-login
14 module-position-event-sounds
15 module-role-cork
16 module-snap-policy
17 module-filter-heuristics
18 module-filter-apply
20 module-null-sink sink_name=auto_null sink_properties='device.description="Dummy Output"'
egress@livekit-egress-sandbox-75587cc5c5-sxxgr:/$ pactl list short sinks || true
2 auto_null module-null-sink.c s16le 2ch 44100Hz SUSPENDED
egress@livekit-egress-sandbox-75587cc5c5-sxxgr:/$tall-airline-16756
12/27/2025, 1:16 PMegress:
containers:
egress:
securityContext:
privileged: true
volumeMounts:
- name: dev-snd
mountPath: /dev/snd
volumes:
- name: dev-snd
hostPath:
path: /dev/snd
type: Directory
• Redeploy the chart and verify /dev/snd exists inside the pod and Pulse shows real sinks.
2) If you cannot mount host devices / do not want privileged:
• Use a virtual sound source that PulseAudio exposes and ensure the egress captures it. You must run a real audio producer inside the pod or route room audio into Pulse (complex).
• Alternative: run a small sidecar that connects to LiveKit and feeds audio into Pulse in the egress pod (I can provide a sample sidecar config if you want this route).
3) Quick test to confirm device fix
• After applying option 1 and redeploying, confirm:
◦ kubectl exec -it <pod> -- ls -l /dev/snd
◦ kubectl exec -it <pod> -- pactl list short sinks
◦ Start egress and check logs — END_RECORDING should not occur immediately.
Notes and safety:
• Mounting /dev/snd and running privileged grants host device access; ensure this fits your security policy.
• If you need least-privilege, enabling user namespaces on hosts + privileged capability or a more restricted set of capabilities may be possible but is more involved.
Tell me which option you want to try (mount host device or sidecar/virtual source) and I’ll give the exact Helm values snippet tailored to your chart and the verification commands.magnificent-monitor-48407
12/27/2025, 1:25 PMtall-airline-16756
12/27/2025, 1:25 PMmagnificent-monitor-48407
12/27/2025, 1:27 PMtall-airline-16756
12/27/2025, 1:27 PMegress:
containers:
egress:
securityContext:
privileged: true
args: []
lifecycle:
postStart:
exec:
command:
- /bin/sh
- -c
- >
pactl load-module module-null-sink sink_name=egress_sink sink_properties=device.description="Egress_Sink" || true &&
pactl set-default-source egress_sink.monitor || true
5) If you prefer using host ALSA instead of null sink, confirm /dev/snd is mounted and that Pulse picks up hw devices (ls -l /dev/snd ; pactl list short sinks). If ALSA devices appear but Pulse still shows SUSPENDED, try restarting PulseAudio:
• pulseaudio --kill || true
• pulseaudio --start
Send me:
• Answer to (1),
• Output of pactl list short sources after step 2,
• First ~200 lines of egress logs if it still aborts.
I’ll analyze those and give the exact values.yaml snippet or alternative sidecar approach as needed.
Sources: Universal Egress | Universal Egressmagnificent-monitor-48407
12/27/2025, 1:31 PMtall-airline-16756
12/27/2025, 1:31 PMpactl load-module module-null-sink ... fails it’s usually because PulseAudio cannot create/load modules due to one of these reasons: missing module binary, insufficient permissions for the Pulse daemon, or Pulse running in a restricted mode (system vs per-user). Let’s narrow and fix it.
First, quick checks inside the pod — paste outputs (one-liners are fine): 1) pulseaudio process info: ps -ef | sed -n '1,120p' | grep -i pulseaudio
2) Pulse daemon mode and config: pulseaudio --version pulseaudio --check && echo running || echo not-running
3) Pulse logs (show recent lines): journalctl --no-pager -u pulseaudio --since "5 minutes ago" 2>/dev/null || true
if journalctl not available, show daemon stderr if present:
ls -l /tmp/pulse* /root/.config/pulse || true
Based on results, try these fixes (pick applicable):
A — If Pulse runs as a system-wide limited user (module loading blocked)
• Restart Pulse in per-user mode inside the container and then load null sink:
pulseaudio --kill || true pulseaudio --start --log-level=debug pactl load-module module-null-sink sink_name=egress_sink sink_properties=device.description="EgressSink" pactl set-default-source egress_sink.monitor
B — If Pulse is running but module load fails due to missing module support
• Confirm modules exist:
pactl list short modules || true ls /usr/lib/pulse-*/modules || ls /usr/lib/pulse/modules || true
• If modules are missing in the image, you must use an image with PulseAudio packages (or install them). Use an image that includes PulseAudio (or build one) so module-null-sink exists.
C — If permissions cause failure (common with non-privileged containers)
• Ensure the container runs privileged or with required capabilities and that /dev/shm and /dev/snd are accessible:
◦ securityContext.privileged: true (or at least add SYS_ADMIN + CAP_IPC_LOCK)
◦ mount /dev/snd (hostPath) and add emptyDir mount for /dev/shm:
volumes:
• name: dev-snd
hostPath: path: /dev/snd
• name: dshm
emptyDir: medium: Memory sizeLimit: 1Gi volumeMounts:
• name: dev-snd
mountPath: /dev/snd
• name: dshm
mountPath: /dev/shm
D — Workaround: pre-create null sink from an init container (ensures Pulse has module loaded before egress starts)
• Add an initContainer that starts a short-lived Pulse instance and loads module, or runs pactl against the pod’s socket. Example lifecycle postStart (values.yaml):
egress:
containers:
egress:
lifecycle:
postStart:
exec:
command:
- /bin/sh
- -c
- |
pulseaudio --start --exit-idle-time=-1 || true
sleep 1
pactl load-module module-null-sink sink_name=egress_sink sink_properties=device.description="Egress_Sink" || true
pactl set-default-source egress_sink.monitor || true
Finally, ensure LiveKit picks the right Pulse source:
• Add env var so egress uses the monitor:
egress:
containers:
egress:
env:
- name: PULSE_SOURCE
value: "egress_sink.monitor"
After trying A or D, verify:
• pactl list short sinks
• pactl list short sources
• pactl list short modules
If you run one of the fixes, paste the outputs of those three pactl commands and the first ~200 lines of the egress logs. I’ll use them to confirm Pulse is active and the egress should record audio.magnificent-monitor-48407
12/27/2025, 1:32 PMpulseaudio process info: ps -ef | sed -n '1,120p' | grep -i pulseaudio
pulseaudio: invalid option -- 'e'
E: [pulseaudio] main.c: Failed to parse command line.
pulseaudio --version pulseaudio --check && echo running || echo not-running
E: [pulseaudio] main.c: Too many arguments.
not-runningtall-airline-16756
12/27/2025, 1:32 PMmagnificent-monitor-48407
12/27/2025, 1:33 PMtall-airline-16756
12/27/2025, 1:33 PMsinkname vs sink_name, sinkproperties vs sink_properties). Let’s confirm the module exists and then load it with the correct syntax.
Please run these exact commands inside the egress pod and paste outputs:
1) List PulseAudio modules to confirm module-null-sink is available: pactl list short modules
2) Load null sink (correct syntax) and set default source: pactl load-module module-null-sink sink_name=egress_sink sink_properties=device.description="EgressSink" || echo "load-module failed" pactl set-default-source egress_sink.monitor || echo "set-default-source failed"
3) Verify sinks/sources after loading: pactl list short sinks pactl list short sources
If load-module still fails, paste the output of command (1) and the exact error from (2). I’ll provide the persistent Helm values.yaml snippet (postStart lifecycle + PULSE_SOURCE env var) once we confirm the null sink can be created.magnificent-monitor-48407
12/27/2025, 1:34 PMtall-airline-16756
12/27/2025, 1:35 PMpactl option names. I can see a module-null-sink already exists as auto_null but is suspended.
Please run these exact commands (one-by-one) inside the egress pod and paste the outputs:
1) Unload the existing auto_null module (if present) and confirm modules: pactl list short modules pactl unload-module module-null-sink || true pactl list short modules
2) Load a properly named null sink and set its monitor as default source: pactl load-module module-null-sink sink_name=egress_sink sink_properties=device.description="Egress_Sink" || echo "load-module failed" pactl set-default-source egress_sink.monitor || echo "set-default-source failed"
3) Verify sinks/sources and module state: pactl list short sinks pactl list short sources pactl list short modules
If any command prints an error, paste that exact error output. Once the sink/monitor show up and are not SUSPENDED, retry the egress and share the first ~200 lines of logs if it still aborts.magnificent-monitor-48407
12/27/2025, 1:35 PMtall-airline-16756
12/27/2025, 1:35 PMmagnificent-monitor-48407
12/27/2025, 1:41 PMtall-airline-16756
12/27/2025, 1:41 PM