gravitational/teleport · error
failed to create decoder
Error message
failed to create decoder
What it means
New in lib/srv/desktop/rdp/decoder/decoder.go returns 'failed to create decoder' when the cgo call to construct the native RDP decoder returns a nil pointer. The decoder is created with dimensions, pixel format and channel IDs; a nil native handle means the underlying FreeRDP/decoder initialization failed. Called from handleServerHello, this aborts the RDP/ desktop playback connection.
Source
Thrown at lib/srv/desktop/rdp/decoder/decoder.go:108
type Decoder struct {
ptr *C.RdpDecoder
}
func New(width, height uint16, opts ...Option) (*Decoder, error) {
var config decoderConfig
for _, opt := range opts {
opt(&config)
}
ptr := C.rdp_decoder_new(
C.uint16_t(width),
C.uint16_t(height),
C.uint16_t(config.ioChannelID),
C.uint16_t(config.userChannelID),
)
if ptr == nil {
return nil, errors.New("failed to create decoder")
}
return &Decoder{ptr: ptr}, nil
}
func (d *Decoder) Release() {
if d.ptr == nil {
return
}
C.rdp_decoder_free(d.ptr)
d.ptr = nil
}
func (d *Decoder) Resize(width, height uint16) {
if d.ptr == nil {
return
}
View on GitHub (pinned to 1283425b60)
Solutions
- Update/rebuild Teleport so the bundled native RDP decoder matches the installed platform libraries
- Inspect the capture/server hello for zero or absurd width/height values
- Reproduce with the desktop RDP playback tooling and check cgo/native library errors in stderr
- Ensure the host has enough memory and the correct shared libraries (ldd) available
Defensive patterns
Strategy: validation
Validate before calling
// validate dimensions before constructing the decoder
if width == 0 || height == 0 {
return errors.New("refusing to create decoder with empty dimensions")
}
// ensure native libs resolve
if out, err := exec.Command("ldd", decoderLibPath).CombinedOutput(); err != nil {
return fmt.Errorf("native decoder libs unresolved: %s", out)
} Type guard
func decoderReady(d *rdpdecoder.Decoder) bool {
return d != nil
} Try / catch
dec, err := rdpdecoder.New(w, h, cfg)
if err != nil {
return fmt.Errorf("rdp decoder unavailable: %w", err)
}
// only then use dec for playback Prevention
- Never ignore the error from decoder New
- Keep native decoder libraries in sync with the Teleport build
- Sanitize width/height from server hello before decoder construction
When it happens
Trigger: handleServerHello processes the RDP server hello and calls New with the negotiated width/height, io/user channel IDs; the C decoder allocation fails (invalid dimensions, failed native init, or memory/allocation failure).
Common situations: Recording/playback of desktop sessions where the native decoder library is missing or incompatible (version mismatch of bundled FreeRDP), zero/negative negotiated dimensions from a malformed capture, or constrained memory on the host running playback.
Related errors
- decoder not initialized
- invalid resize dimensions
- xsession was terminated
- decoder has no pixel format
- failed to resize crop region
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/6f1b9b459e972310.
Report an issue: GitHub.