gravitational/teleport · error
xsession was terminated
Error message
xsession was terminated
What it means
In lib/srv/desktop/linux_server.go the desktop session supervises an xsession (Xorg/Xvfb process). When the xsession's error channel yields a nil error while the session goroutine ends, the watcher returns 'xsession was terminated', meaning the X server process exited without reporting a specific error.
Source
Thrown at lib/srv/desktop/linux_server.go:815
AuthorityFile: sess.backend.AuthorityFile,
})
if err != nil {
return trace.Wrap(err, "Couldn't start Xsession")
}
sess.cmd = cmd
sess.errGroup.Go(func() error {
errCh := make(chan error, 1)
go func() {
errCh <- cmd.Wait()
}()
select {
case <-sess.ctx.Done():
return nil
case err := <-errCh:
if err != nil {
return trace.Wrap(err, "xsession was terminated with error")
}
return trace.Wrap(errors.New("xsession was terminated"))
}
})
return nil
}
func (sess *linuxSession) handleClientScreenSpec(m *tdpb.ClientScreenSpec) error {
if m.Width > types.MaxRDPScreenWidth || m.Height > types.MaxRDPScreenHeight {
return trace.BadParameter("invalid screen size %dx%d, maximum is %dx%d", m.Width, m.Height, types.MaxRDPScreenWidth, types.MaxRDPScreenHeight)
}
sess.resizeMu.Lock()
defer sess.resizeMu.Unlock()
width := uint16(m.Width)
height := uint16(m.Height)
sess.screenSize.Width = width
sess.screenSize.Height = height
sess.sendFullScreen = true
if err := sess.backend.Resize(width, height); err != nil {
return trace.Wrap(err, "Couldn't resize backend")View on GitHub (pinned to 1283425b60)
Solutions
- Check systemd/journal logs for the Xorg/Xvfb process crash reason
- Verify display server binaries and GPU/dummy drivers are installed and compatible
- Check dmesg for OOM kills and add memory or limit concurrent desktop sessions
- Have the user reconnect — a new session typically starts a fresh xsession
Defensive patterns
Strategy: retry
Validate before calling
// verify the X server binary exists and host has memory before starting a session
if _, err := exec.LookPath("Xorg"); err != nil {
return fmt.Errorf("display server missing: %w", err)
}
if avail := memAvailable(); avail < minDesktopSessionMem {
return fmt.Errorf("insufficient memory for desktop session")
} Try / catch
err := attachDesktopSession(ctx, sessionID)
if isXsessionTerminated(err) {
log.Printf("xsession died without error; check journalctl for Xorg crash")
return retrySession(ctx, sessionID)
} Prevention
- Monitor host memory to prevent OOM kills of Xorg/Xvfb
- Install correct GPU/dummy drivers for headless desktop access
- Alert on frequent desktop session termination events
When it happens
Trigger: The X server process backing the desktop session exits (crash, SIGKILL, OOM kill, or clean exit) and its error channel closes with no error; the select in the session waiter converts that into this wrapped trace error.
Common situations: Linux desktop access sessions where Xorg crashes due to a bad driver/mode, the host is under memory pressure (OOM killer terminates Xvfb/Xorg), or the session is forcibly terminated by an admin.
Related errors
- failed to create decoder
- unable to serve request due to an app configuration error. C
- unable to serve the request due to an internal error. Contac
- tokens quota exceeded. Contact your Teleport administrator
- the inference provider returned an unexpected error. Contact
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/b13961a251c4a80c.
Report an issue: GitHub.