for (const enc of params.encodings) Object.assign(enc, patch) writes the samemaxBitrate into every encoding. EC/LiveKit publishes screenshare with simulcast (the comment at line 177 says so), so a 1.5 Mbps "cap" becomes up to 1.5 Mbps on each of the low/medium/high layers — an aggregate of ~4.5 Mbps, three times what the host asked for. It also raises the low layers far above their presets, which distorts LiveKit's layer-selection/bandwidth-estimation behaviour. The server-side voice-limit-guard is described as the backstop, which suggests the cap is expected to actually hold.
How to trigger
Set a screenshare bitrate cap while sharing a screen and read sender.getParameters().encodings / outbound-rtp stats; the sum exceeds the cap.
Suggested fix
Cap only the highest encoding to the requested value and scale the lower layers proportionally (or divide the budget across active layers) rather than assigning the same maxBitrate to all.
Filed from the September 2026 audit (branch lotus).
**Severity:** medium · **Type:** bug · **Confidence:** medium
**Location:** `src/lotus/lotusQuality.ts:177-180`
### Problem
`for (const enc of params.encodings) Object.assign(enc, patch)` writes the *same* `maxBitrate` into every encoding. EC/LiveKit publishes screenshare with simulcast (the comment at line 177 says so), so a 1.5 Mbps "cap" becomes up to 1.5 Mbps on each of the low/medium/high layers — an aggregate of ~4.5 Mbps, three times what the host asked for. It also *raises* the low layers far above their presets, which distorts LiveKit's layer-selection/bandwidth-estimation behaviour. The server-side voice-limit-guard is described as the backstop, which suggests the cap is expected to actually hold.
### How to trigger
Set a screenshare bitrate cap while sharing a screen and read `sender.getParameters().encodings` / outbound-rtp stats; the sum exceeds the cap.
### Suggested fix
Cap only the highest encoding to the requested value and scale the lower layers proportionally (or divide the budget across active layers) rather than assigning the same `maxBitrate` to all.
---
_Filed from the September 2026 audit (branch `lotus`)._
jared
added this to the EC fork audit 2026-09 · Medium & Low milestone 2026-09-12 02:13:02 -04:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Severity: medium · Type: bug · Confidence: medium
Location:
src/lotus/lotusQuality.ts:177-180Problem
for (const enc of params.encodings) Object.assign(enc, patch)writes the samemaxBitrateinto every encoding. EC/LiveKit publishes screenshare with simulcast (the comment at line 177 says so), so a 1.5 Mbps "cap" becomes up to 1.5 Mbps on each of the low/medium/high layers — an aggregate of ~4.5 Mbps, three times what the host asked for. It also raises the low layers far above their presets, which distorts LiveKit's layer-selection/bandwidth-estimation behaviour. The server-side voice-limit-guard is described as the backstop, which suggests the cap is expected to actually hold.How to trigger
Set a screenshare bitrate cap while sharing a screen and read
sender.getParameters().encodings/ outbound-rtp stats; the sum exceeds the cap.Suggested fix
Cap only the highest encoding to the requested value and scale the lower layers proportionally (or divide the budget across active layers) rather than assigning the same
maxBitrateto all.Filed from the September 2026 audit (branch
lotus).