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

Open
#1,693 5 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.