Devolutions / Devolutions/IronRDP
Fast-path RLE bitmap decode fails against xrdp (16bpp): "not enough bytes: expected 2, but got 1" + "unsupported fast-path update code" — causes visible screen corruption
- Dominant language
- Rust
- Stars
- 3.2k
- Forks
- 275
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 189
Description
## Title
Fast-path RLE bitmap decode fails against xrdp (16bpp): "not enough bytes: expected 2, but got 1" + "unsupported fast-path update code" — causes visible screen corruption
## Environment
- `@devolutions/iron-remote-desktop` 0.11.0 (npm, latest)
- `@devolutions/iron-remote-desktop-rdp` 0.7.0 (npm, latest)
- Client: browser (WASM), connecting through `devolutions-gateway` 2026.2.4 (RDCleanPath)
- Server: xrdp 0.10.6.1-2+kali1 + xorgxrdp 1:0.10.5-2 on Kali GNU/Linux Rolling 2026.3, desktop session = Xfce 4.20
- Server capabilities as sent in `ServerDemandActive`: `Bitmap { pref_bits_per_pix: 16, desktop_resize_flag: true }`, GFX/EGFX pipeline NOT used for this connection — negotiated via the classic fast-path bitmap-orders channel instead.
## What happens
After a normal, successful connection (TLS handshake OK, login OK, capability exchange OK), the client logs repeated warnings while receiving bitmap updates, and the on-screen result is visibly corrupted (diagonal shearing / torn tiles), while mouse/keyboard input keep working.
Representative log lines from one session (122 total `BitmapData` fast-path updates received, all `bits_per_pixel: 16`, 2 of them fail to decode):
```
DEBUG ironrdp_session::fast_path: Non-32 bpp compressed RLE_BITMAP_STREAM bpp=16
WARN ironrdp_session::fast_path: Invalid RLE-compressed bitmap: not enough bytes: expected 2 bytes, but got 1
WARN ironrdp_session::fast_path: Received invalid Fast-Path update field="updateCode" reason="unsupported fast-path update code"
```
One of the `BitmapData` PDUs immediately preceding a failure, for reference:
```
BitmapData { rectangle: InclusiveRectangle { left: 385, top: 427, right: 594, bottom: 448 }, width: 212, height: 22, bits_per_pixel: 16, compression_flags: Compression(BITMAP_COMPRESSION | NO_BITMAP_COMPRESSION_HDR), compressed_data_header: None, bitmap_data.len(): 54 }
```
## What I ruled out (server-side, not a config issue)
Before filing, I checked whether this was an xrdp misconfiguration on our end:
- `desktop_width`/`desktop_height` requested by the client are always rounded to a multiple of 4 (e.g. 796x1020, 900x636) — not a stride/alignment issue on the client side.
- Toggling `bitmap_compression=false` in `xrdp.ini` (forces raw/uncompressed bitmap updates instead of RLE): connection got noticeably slower but showed the exact same corruption — so it isn't specific to the RLE codec's compression math alone, something in the fast-path bitmap-orders handling itself is affected, or xrdp still exercises the same code path regardless of that flag.
- `max_bpp=32` is already set in `xrdp.ini` (the server's own ceiling), yet `preferredBitsPerPixel` stays 16 in `ServerDemandActive` regardless — this doesn't look configurable from our side.
- Forcing the X11 screen depth to 32 in `xorg.conf` (`DefaultDepth`/`Depth`) breaks the xrdp Xorg session entirely (`X server could not be started`) — not viable.
- `iron-remote-desktop`'s `ConfigBuilder` has no method to request a specific color depth (only `withUsername/withPassword/withServerDomain/withDestination/withProxyAddress/withAuthToken/withExtension/withDesktopSize`), so we can't influence this from the client config either.
- Confirmed with `xfreerdp` (FreeRDP 2.11.5) against the same xrdp instance: connects and renders perfectly clean at the same resolution/session — so this isn't an xrdp/xorgxrdp bug, it's specific to how `ironrdp_session::fast_path` parses this server's 16bpp interleaved-RLE stream.
## Impact
Legacy/non-GFX xrdp sessions (very common — Linux desktop targets, not just Windows) render with visible tearing/corruption. Reproducible every connection against this server, ~2 failed tile decodes out of ~122 per session in our testing, but visually noticeable because failures desync the bitmap cache for subsequent frames referencing the same tile.
## Contact
adelson-amorim@outlook.com — happy to provide a packet capture / full session log (currently ~190MB with embedded frame data) if useful for a repro.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in the ironrdp_session::fast_path handling for BitmapData updates, focusing on 16bpp RLE_BITMAP_STREAM parsing and the unsupported update-code warning. Reproduce against the described xrdp 0.10.6.1 setup, using the provided failing log and bitmap dimensions as reference. Done means the affected 16bpp fast-path stream decodes without warnings and renders without visible corruption.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100