Troubleshooting recordings#
Introduction#
This is a guide to help identify and solve common issues related to recordings in OpenVidu.
Recordings are handled by the Egress service in OpenVidu, built on top of LiveKit Egress . There are some general considerations to take into account:
- Recordings are CPU intensive operations. For recordings to work smoothly, the nodes hosting the Egress service must have sufficient free cores.
- The first symptom of something going wrong with recordings is usually missing recordings: you are expecting recording files to be available in your storage, but they are simply not there. Other common symptom is receiving an error
503 Service Unavailablewhen starting a new recording on-demand. - To be proactive when dealing with recording issues, it is highly recommended to enable webhooks in your OpenVidu deployment (learn how) and monitor it from your application's backend. In this way you can be notified of Egress-related events and errors as they happen.
On-demand vs Automatic recordings#
Recordings can be started on-demand or automatically:
- On-demand recordings are started by calling any of the these operations of the LiveKit Egress API :
StartRoomCompositeEgressStartTrackCompositeEgressStartParticipantEgressStartTrackEgressStartWebEgress
- Automatic recordings are started when a room is created with auto-egress enabled. To do so just include an
egressfield when calling theCreateRoommethod: then the room will be automatically recorded during its lifetime. See auto-egress documentation for more details.
Warning
It is important to distinguish between on-demand recordings and automatic recordings for a simple reason: your application is able to catch and handle errors when starting on-demand recordings, while automatic recordings will fail silently.
List of possible recording issues#
Below are some of the most common issues related to recordings in OpenVidu, along with their symptoms and possible solutions.
CPU exhausted#
Description
There are not enough free CPU cores to start a new egress.
Symptoms
- The operation to start a new egress returns a
503 Service Unavailableerror (text of the error:no response from servers). This applies when starting egress on-demand from your application. -
Log lines of level
WARNdisplayingcan not accept requestin service "egress". A typical log line of this type looks like this:2026-03-10T10:47:56.215Z WARN egress stats/monitor.go:204 can not accept request {"nodeID": "NE_ynSpFdP6xfAS", "clusterID": "", "total": 16, "available": 3.175, "pending": 0, "used": 6.258, "activeRequests": 4, "activeWeb": 4, "memory": 2.9882, "memorySource": "proc_rss", "required": 4, "canAccept": false, "reason": "cpu", "error": "not enough CPU"} -
Log lines displaying
CPU exhaustedin service "egress". - Log lines displaying
pipeline frozenin service "egress". - Log lines displaying
Can't record audio fast enoughin service "egress".
Solutions
- Scale out your OpenVidu deployment: deploy it in nodes with more CPU cores or add more Media Nodes to your cluster.
- Consider using a less CPU intensive egress type: Track Egress does not require transcoding and composition, so it is much less CPU intensive than other egress types such as Room Composite Egress .
-
Review your
egress.yamlconfiguration file, specifically the properties withincpu_cost:cpu_cost: max_cpu_utilization: 0.8 room_composite_cpu_cost: 2.0 audio_room_composite_cpu_cost: 1.0 web_cpu_cost: 2.0 audio_web_cpu_cost: 0.5 participant_cpu_cost: 1.0 track_composite_cpu_cost: 1.0 track_cpu_cost: 0.5These properties determine two different things. OpenVidu configures sane defaults in all of them to prevent CPU exhaustion in most scenarios, but you may want to review and adjust them according to your specific use case:
- The
max_cpu_utilizationproperty is the CPU usage threshold of the node above which the egress service won't accept new requests. - All the
[...]_cpu_costproperties determine the amount of free CPU cores required in the node to accept a new egress request of each type.
- The
We strongly recommend reading the Load balancing of egress documentation.
Wrong auto-egress configuration#
Description
By default, OpenVidu will automatically create a new room when a user tries to connect to a room that does not exist yet. This behavior can be disabled in livekit.yaml configuration file:
When a room is auto-created on participant join, OpenVidu uses the room settings included in that participant’s token (RoomConfiguration ).
A common problem appears when these chain of events happens:
- Your application's backend explicitly creates a room with a specific
RoomConfiguration. For example, with anegressfield to enable auto-egress. - The room is unexpectedly deleted because of a timeout (properties
departure_timeoutorempty_timeoutinlivekit.yaml). - A participant tries to join the room using a token that does not include the same
egressfield in itsRoomConfiguration. - OpenVidu auto-creates the room again, but now using the token’s
RoomConfiguration, not the original one.
In this case, the room will not have auto-egress enabled, and therefore it will not be recorded. This behavior is also silent, as it is not an actual error but just a logic issue in your application.
Symptoms
You encounter this set of logs related to a room (in this example, room DailyMeeting):
-
You explicitly create the room from your application's backend with autoegress enabled:
2026-01-19T09:00:03.302Z INFO openvidu.api service/twirp.go:128 API RoomService.CreateRoom {"service": "RoomService", "method": "CreateRoom", "room": "DailyMeeting", "request": {"name": "DailyMeeting", "metadata": "<redacted (0 bytes)>", "egress": {"tracks": {"filepath": "recordings/{room_name}/{track_source}-{time}"}}}, "duration": "8.808101ms", "status": "200"} -
The room is automatically deleted due to a timeout:
-
A participant connects to the room with a token that does not have autoegress enabled (no
egressfield in itsRoomConfig):2026-01-19T09:00:02.925Z INFO openvidu service/roommanager.go:432 starting RTC session {"room": "DailyMeeting", "roomID": "RM_u8NSwnuczia6", "participant": "Alice", "pID": "PA_CMwzkoL6Vp3q", "remote": false, "nodeID": "ND_QLa7LB7937db", "numParticipants": 1, "participantInit": {"Identity": "1589577", "Reconnect": false, "ReconnectReason": "RR_UNKNOWN", "AutoSubscribe": false, "Client": {...}, "Grants": {...}, "SIP": {...}, "Agent": {...}, "RoomConfig": {"metadata": "<redacted (0 bytes)>"}, "RoomPreset": ""}, "Region": "", "AdaptiveStream": true, "ID": "", "SubscriberAllowPause": "not-set", "DisableICELite": false, "CreateRoom": {"name": "DailyMeeting", "metadata": "<redacted (0 bytes)>"}}
Solutions
- Consider using on-demand egress requests instead of auto egress to record rooms.
-
Consider disabling auto-creation of rooms in file
livekit.yaml. This enforces rooms to always be created explicitly from your backend before a participant can join to it with a token. Of course, it also requires handling connection errors in the frontend if a participant tries to join a non-existing room. -
If you want both auto-egress and auto-creation of rooms, make sure to include the same
egressfield in theRoomConfigurationin both theCreateRoomrequest and the participant's access token . In this way rooms will always behave the same way, no matter if they are explicitly created from your backend or auto-created when a participant tries to join. -
Increase the room timeout properties in
livekit.yaml. This can reduce the probability of rooms being cleaned up before a participant tries to join:
Misconfiguration of external storage#
Description
You have configured an external storage for your recordings, but the recording files are not being uploaded to it. This can be caused by a misconfiguration or a connectivity issue between OpenVidu nodes and the external storage.
External storage is configured in the egress.yaml configuration file globally (with storage property):
You can also configure external storage programmatically on a per-request basis when starting an egress.
Symptoms
-
You don't see recording files in your external storage, and the backup folder for egress in your OpenVidu node (
/opt/openvidu/data/egress_data/home/egress/backup_storage) is accumulating files:root@media-node-1:/opt/openvidu/data/egress_data/home/egress/backup_storage# ls -la total 19036 drwxr-xr-x 2 admin admin 4096 Mar 10 14:16 . drwxr-xr-x 8 admin admin 4096 Mar 10 10:47 .. -rw-r--r-- 1 admin root 335 Mar 10 14:11 EG_53MKZu5havzx.json -rw-r--r-- 1 admin root 335 Mar 10 14:09 EG_ZgeLTs8FdtzU.json -rw-r--r-- 1 admin root 448 Mar 10 14:16 EG_fnvyJkL8YVyt.json -rw-r--r-- 1 admin root 14721461 Mar 10 14:09 RoomComposite-RM_Mi5Lau9HWGQ8-TestRoom-2026-03-10T140854.mp4 -rw-r--r-- 1 admin root 1772593 Mar 10 14:11 RoomComposite-RM_Mi5Lau9HWGQ8-TestRoom2-2026-03-10T141055.mp4 -rw-r--r-- 1 admin root 2969013 Mar 10 14:16 TrackComposite-RM_JpcnziWBTEdY-TestRoom3-2026-03-10T141625.mp4 -
The EgressInfo objects returned by the Egress API or included in the
egress_endedwebhook event contains:- Field
backup_storage_usedwith valuetrue. - Or any other field with the substring
backup_storagein its value (E.g.manifestLocation = '/home/egress/backup_storage/EG_f5nHLam4xLb8.json').
- Field
Solutions
- Review the configuration of the external storage: in the
egress.yamlif you are using the global declarative configuration, or in the body of theCreateRoomorStartEgressoperations if you are using the programmatic per-request configuration. - Review the connectivity between your OpenVidu nodes and the external storage. Check if there are any network issues or firewall rules preventing OpenVidu nodes from reaching the external storage.
No disk space free#
Description
There is not enough free disk space in the node hosting the egress to start a new recording.
Symptoms
- The operation to start a new egress returns a
503 Service Unavailableerror (text of the error:no response from servers). This applies when starting egress on-demand from your application. -
The egress service logs a warning message
can not accept requestfollowed by a JSON object containing"error": "not enough disk space":{"nodeID": "NE_xRcu2tzJD5mC", "clusterID": "", "total": 16, "available": 12.022278481012659, "pending": 0, "used": 0, "activeRequests": 0, "activeWeb": 0, "memory": 0.06648635864257812, "memorySource": "proc_rss", "availableDiskMB": 30704.07421875, "minDiskSpaceMB": 99999999, "canAccept": false, "reason": "disk", "error": "not enough disk space"} -
Webhook event
egress_endedwith statusEGRESS_FAILEDand errormkdir /home/egress/tmp/EGH_XXXXXXXXXXXX: no space left on device{"event": "egress_ended", "id": "EV_zxMEf5XPp5yV", "webhookTime": 1771329474, "url": "http://127.0.0.1:6080/livekit/webhook", "egressID": "", "status": "EGRESS_FAILED", "error": "mkdir /home/egress/tmp/EGH_XXXXXXXXXXXX: no space left on device", "queueDuration": "7.815288ms", "qLen": 0, "sendDuration": "8.05349ms"}
Solutions
Increase disk space in the node hosting the egress.
Egress CPU overload killer#
Description
By default, OpenVidu will kill active egresses under sustained high CPU load (see Egress CPU overload killer). This is generally expected and desired, but it can impact active egresses, causing them to be interrupted.
Symptoms
- The recordings are incomplete. They appear to be cut off unexpectedly.
- Log lines of level
WARNdisplayingkilling egress due to sustained high cpuin service "egress".
Solutions
- You can disable the Egress CPU overload killer by setting property
openvidu.disable_cpu_overload_killertotruein theegress.yamlconfiguration file. This must be done with caution and care, as it could lead to overloading the entire Media Node and affecting the performance of other processes. - In the end this is just an under-provisioning issue: consider scaling out your OpenVidu deployment. Deploy it in nodes with more CPU cores or add more Media Nodes to your cluster.