tracel-ai/burn · error

Cannot host a remote server on a capture device

Error message

Cannot host a remote server on a capture device

What it means

This panic occurs when hosting a remote server on a Capture device. Capture devices record/replay op traces rather than executing them via a BackendIr backend, so they cannot serve as the execution backend for a remote server. The server panics immediately rather than producing broken recordings.

Source

Thrown at crates/burn-dispatch/src/remote_server.rs:105

                $body
            }
            #[cfg(feature = "ndarray")]
            DispatchDevice::NdArray(_) => {
                type $b = NdArray;
                let $devices = host_devices!(DispatchDeviceId::NdArray, NdArray);
                $body
            }
            #[cfg(feature = "tch")]
            DispatchDevice::LibTorch(_) => {
                panic!("LibTorch is not supported as a remote-server backend (no BackendIr impl)")
            }
            #[cfg(feature = "remote")]
            DispatchDevice::Remote(_) => {
                panic!("Cannot host a remote server on a remote device")
            }
            #[cfg(feature = "capture")]
            DispatchDevice::Capture(_) => {
                panic!("Cannot host a remote server on a capture device")
            }
            #[cfg(feature = "autodiff")]
            DispatchDevice::Autodiff(_) => {
                unreachable!("Autodiff stripped by .inner() above")
            }
        }
    };
}

/// Start a remote-execution server for `device`'s backend, blocking the current thread.
///
/// `device` selects the backend; `channel` selects the transport. The server hosts that backend's
/// devices, indexed by hardware device index. Use [`start_async`] for the async counterpart.
#[cfg(not(target_family = "wasm"))]
pub fn start(device: DispatchDevice, channel: Channel) {
    with_backend!(device, |B, devices| {
        burn_remote::server::RemoteServerBuilder::<B>::new(devices)
            .channel(channel)

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Use the underlying (un-captured) device for the server host, e.g., DispatchDevice::NdArray over the raw backend device.
  2. Disable the `capture` feature in the server binary if capture wrapping is unintentional.
  3. Keep capture purely client-side; the server must always run a BackendIr-capable local backend.

Example fix

// before
let device = DispatchDevice::Capture(capture_device);
// after
let device = DispatchDevice::NdArray(ndarray_device); // use capture_device.inner() locally instead
Defensive patterns

Strategy: validation

Validate before calling

match device {
    DispatchDevice::Capture(_) => return Err("cannot host a remote server on a capture device".into()),
    _ => {}
}

Type guard

fn is_host_capable_device(d: &DispatchDevice) -> bool {
    !matches!(d, DispatchDevice::Capture(_) | DispatchDevice::Remote(_) | DispatchDevice::LibTorch(_))
}

Prevention

When it happens

Trigger: Starting a remote server whose host device resolves to DispatchDevice::Capture(_) (feature "capture" enabled and the capture device passed as the server device).

Common situations: Reusing a capture/profiling session's device configuration for the server binary; build configurations where the capture feature wraps devices by default and the server picks up the wrapped device.

Related errors


AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/9b25b5b90a9a7de0. Report an issue: GitHub.