A CSI camera that captures perfectly at the bench monitor and dies the moment you log in through a remote-desktop client is a common trap on embedded Linux boards. The log ends in BadParameter inside FrameConsumerImpl.cpp, followed by Failed to create FrameConsumer, and it reads like a broken camera. It is not: the trace shows the sensor was detected, the pipeline reached PLAYING, and the capture stack stopped at the one step that needs a real display. This guide reads the trace line by line, gives you a five-minute test that separates the sensor from the session, works the arithmetic on a real module, and walks the three fixes that hold up: capture without a display consumer, preview locally while streaming the result, or move to an interface with no display dependency.
What the error trace says
Start from the top of your own log. Using winsys: x11 means your preview sink — the log names eglglessink0 — grabbed the X11 window system of the session it runs in, and registered that display's EGL context on the pipeline. The pipeline then reached PLAYING on the system clock, so clocks and element negotiation were fine. The next line, GST_ARGUS: Creating output stream (Argus), is the good news: the capture stack opened the camera device, the sensor answered, and frame capture was about to start.
Then the failure, and the line worth committing to memory: 'Error BadParameter: (propagating from src/eglstream/FrameConsumerImpl.cpp, function initialize, line 89)'. It repeats through FrameConsumerImpl.cpp create at line 44, and the source element reports it as Failed to create FrameConsumer at threadInitialize:320, propagated through threadFunction:241 and waitRunning:203 before execute:806 ends the run. Your log closes with EOS and Execution ended after 0:00:01.031317846 — about one second of pipeline life, zero frames.
Read as a whole: everything through sensor bring-up succeeded, and the process died creating the output stream's consumer. That consumer is the display-side half of the stream, the piece that receives frames for rendering, and it is created against the EGL display of the session the capture process runs in. The same element fails differently when the device index is wrong, which the guide to nvarguscamerasrc capturing the desktop screen covers; the habit of separating capture from rendering before debugging anything else is the same one behind camera window opens but no video.
Why a remote-desktop session breaks stream creation
At the bench, the board's desktop session owns a real, accelerated display, and EGL can build the consumer the output stream needs. A remote-desktop client replaces that display with a virtual one, and some servers hand out a software-rendered X display with no usable accelerated EGL: the xrdp project documents that several Linux desktop environments work poorly or not at all over its sessions, and VNC sessions show the same BadParameter trace in public reports. When consumer creation is attempted against a display that cannot service it, the call returns BadParameter — exactly the line 89 in your log.
The fault therefore travels with the session, not with the camera. Same board, same module, same pipeline: it runs when the local display owns the session and fails when a remote client does. The pattern extends past desktop remoting — an Argus camera driven from a remote RViz visualization client freezes in the same family, which notes on fixing Argus camera freezes over remote RViz walk through — and the desktop-side twin of the problem, an EGL preview that cannot obtain a working display context, is covered in fixing an EGL DRI3 preview failure on an embedded Linux desktop.
Separate the sensor from the session in five minutes
The capture stack's own developer guide gives the clean test: the section Applications Using V4L2 IOCTL Directly checks basic camera function with no display consumer involved. Work it in this order.
- Open a plain shell on the board — SSH is fine, no desktop needed — and run a raw V4L2 capture of a fixed frame count from the camera's video device, using the streaming check from that guide section. Pick the count before you start; 90 frames works well at a 30 fps mode.
- Time the run and compare it with the mode's frame rate. The arithmetic is in the next section; the pass line is about 95% of the mode rate.
- If the frames arrive at rate, the module, the flex cable, the driver and the CSI link are all good. The display session is the fault: go straight to the fixes.
- If raw capture fails instead — no video device, timeouts, dropped frames — the problem sits below the session. A missing device node usually means the capture interface is not enabled (CSI camera V4L2 no such device error); if you are assembling the capture stack itself, start from building the capture stack for a machine-vision camera.
Worked example: an IMX219-160 module over a remote session
The inputs, and where each comes from: the module is the IMX219-160 camera module from the failing set-up, and its 1080p mode runs at 30 fps (the module's documented mode); the observed failure is an Argus pipeline that ends after 1.031 s with zero frames (the trace above, 0:00:01.031317846); the test load is 90 frames, a fixed count chosen here; and a 4:2:0 frame packs to 1.5 bytes per pixel, the standard size for that format.
Two rules decide the case. First, a healthy sensor captures a fixed frame count at its mode's frame rate no matter which session you run from, so the test time is frames divided by frame rate. Second, raw frames cost bandwidth in proportion to their pixels, so the rate you would have to send over a network is width times height times 1.5 bytes, times the frame rate:
The raw-path test should take 90 ÷ 30 = 3.0 s. Allow for scheduler jitter and set the pass line at 95% of mode rate: 30 × 0.95 = 28.5 fps, so 90 frames must finish in 90 ÷ 28.5 = 3.16 s or less. The failed Argus run has the opposite signature: it ended at 1.031 s, which is 1.031 × 30 ≈ 31 frame periods after PLAYING, with zero frames captured — the second went into failing stream creation, not into frames.
Now the cost of moving the results raw: 1920 × 1080 × 1.5 = 3,110,400 bytes per frame; at 30 fps that is 3,110,400 × 30 = 93,312,000 bytes per second, about 93.3 MB/s, or ×8 = 746,496,000 bits per second ≈ 746 Mb/s. An encoded 1080p30 H.264 stream at a typical 6 Mb/s carries 6 ÷ 8 = 0.75 MB/s, so the encoded path moves 93.3 ÷ 0.75 ≈ 124 times less data.
Result: a raw capture that finishes within 3.16 s proves the sensor, and the 1.031 s BadParameter death proves the display consumer failed. Decision: with raw capture holding at least 95% of mode rate and BadParameter inside about one second of PLAYING, the camera is healthy and the fix is the capture path — capture or encode on the board, and move at most the ~6 Mb/s encoded stream across the network, never the ~746 Mb/s raw feed.
The fixes, in the order to try them
Fix 1 — capture without a display consumer. End the pipeline in a sink that takes plain buffers instead of EGL frames: fakesink for a pure functional run, or your encoder when you want the frames out. On most capture-stack versions a bare nvarguscamerasrc-to-fakesink run works from an SSH shell; if your version still asks for an EGL consumer, put the board's buffer-converter element — the one that turns EGL-stream frames into plain memory buffers — between producer and sink, and the producer then has a non-display consumer. Verify by watching the pipeline stay in PLAYING past the one-second mark while a frame counter climbs; the failed run died inside 1.031 s.
Fix 2 — preview where the display is, stream the result. For focusing and lighting work you want a live picture, so run that preview on the board's own display and move the result across the network as an encoded stream. The pipeline pattern is in streaming a MIPI camera over RTSP with GStreamer and the viewing side in display an RTSP camera stream in an HMI; if a remote client still needs a window, putting the display window on the front panel is the cleaner arrangement. At 1080p30 this is the ~6 Mb/s path against ~746 Mb/s raw — only one of the two survives a network hop.
Fix 3 — change the interface. If the station has no local display and you control the hardware choice, pick a camera whose transport never passes through the window system. GigE and USB3 board-level cameras hand buffers to your process over their own link and run from a bare SSH session; the trade-offs between the CSI module you have and a USB3 module are laid out in MIPI CSI versus USB3 for a raw Bayer stream. Two modules built for exactly this:
- Sensor format
- 1/1.8"
- Lens mount
- C-mount
- Sensor format
- 1/2.9"
- Lens mount
- M12
The LS-BCM-0003 runs 120 fps over USB3 with a global shutter, which also makes it the faster pick for moving parts. The MV-CB016-10GM-M-W is a 1.6 MP GigE module with an M12 mount and a global shutter, at home where a small camera near the part beats a large camera far from it.
When it really is the camera or the cable
BadParameter inside FrameConsumerImpl never points at hardware; a failing raw V4L2 test does. A sensor that is detected but never streams points at power, clocks or the device-tree binding — when a MIPI sensor is detected but streaming fails sorts those out. A failure at a specific startup stage is the MIPI camera startup failure walkthrough. Frames that arrive but drop or tear usually mean the pipeline mode does not match the sensor output, which CSI camera short frame errors explains. Before any of that, reseat the flex cable: seat, latch, orientation — the cheapest fault and a common one. One rule keeps you honest: session-level failures kill the pipeline in about one second with BadParameter, and hardware faults show up in the raw V4L2 test.
Bench habits that keep capture off the display
- Decide per station where preview runs. A display-consuming sink belongs on a session backed by the physical display, never on a virtual desktop.
- Keep the known-good frame-count test per camera and mode, and rerun it after any capture-stack update; the one-second BadParameter signature then proves itself again.
- Move results across the network encoded, never raw: at 1080p30 the raw feed costs ~746 Mb/s against ~6 Mb/s encoded.
- For stations with no local display at all, prefer GigE or USB3 capture hardware, so no capture path ever depends on the window system.
To pick hardware for a rebuild, start at the camera finder, then configure the whole chain in the camera configurator; the area scan cameras range covers standard modules and the board-level cameras range covers modules built to sit inside your own machine. The systems topic page collects the neighboring CSI troubleshooting guides, and the contact page is the route to a specific match for your board and mount.
Questions
Does a BadParameter FrameConsumer error mean the camera module is broken?
No. The trace shows Creating output stream (Argus), which means the sensor was detected and the pipeline reached stream setup; only the display-side consumer failed. Broken hardware fails differently: no video device, open timeouts, or a raw capture that drops frames. Run the fixed-frame-count V4L2 test — if the frames arrive at the mode's rate, the module and the CSI link are healthy and the display session is the fault.
Why does the same pipeline work when a monitor is plugged in?
With a physical display, the board's desktop session owns accelerated graphics and EGL can create the consumer the Argus output stream needs. A remote-desktop client substitutes a virtual display, often with no accelerated EGL, and consumer creation returns BadParameter. Nothing on the camera side changed between the two runs — only the display the capture process could see.
Which remote-desktop tools trigger this failure?
Any client or server that substitutes a virtual display: VNC sessions, RDP servers and forwarded X sessions all appear in reports of this trace. Some Linux RDP servers render software-only on several desktop environments, by their own documentation, so the display your capture process sees may have no usable EGL at all. Judge the display, not the client.
Can I capture CSI frames with no desktop session at all?
Yes, as long as the pipeline never asks for a display consumer. Raw V4L2 capture runs from a plain shell, and pipelines ending in a non-display sink run the same way. Keep interactive previews on the board's own display and ship the result as an encoded stream — about 6 Mb/s for 1080p30, against roughly 746 Mb/s for the raw frames.
Which camera interface avoids display-dependent capture entirely?
GigE and USB3. Both hand buffers to your process over their own link, with no EGL stream and no window system in the path, so capture runs under SSH, in services, and on stations with no display. Board-level modules in those two interfaces are made for exactly that role; filter the camera finder by interface to see the range.

