Two GMSL cameras on one embedded host, and a failure that looks impossible: the vendor's enumeration tool lists both cameras as AVAILABLE, then your application stops at Camera Open: FAILURE. That combination is not contradictory. Detection and streaming are different checks, and with more than one camera the usual culprit is how your code selects the device — by index or name instead of serial number. This guide walks the five causes in the order to test them, gives you a ten-frame test for every video node, and ends with the startup self-check that keeps a multi-camera rig opening on the first try.
Detection is not streaming
AVAILABLE means the driver enumerated the device descriptor. Camera Open asks for more: every video node that camera exposes must accept a stream, no other process may hold one, and the camera SDK and the GMSL driver must agree on the access path. A camera can pass the first check and fail any of the other three.
If no camera lists at all — not even as AVAILABLE — the fault sits upstream of this guide: power, cabling or a missing driver. GMSL camera not detected: check capture-card power and cabling covers that case. The same detection-versus-streaming split exists on USB, where a powered camera that never enumerates has its own USB link checks after a cable swap.
The five causes and the test that separates them
Work down the table in order; the first three causes cover most open failures on a rig that enumerates cleanly.
| # | Cause | Test | Fix |
|---|---|---|---|
| 1 | Your open call resolves by index or device name | Print the serial of the camera it actually selected | Select by serial number |
| 2 | Another process holds the video node | Close every viewer and container, then open again | One owner per node |
| 3 | One video node never streams | Ten-frame capture on each node | Reseat or replace the cable, recheck the deserializer binding |
| 4 | SDK and GMSL driver out of step | Print both versions, compare with the vendor pairing | Update both together |
| 5 | Permissions on the node | One open as root, diagnostic only | Put the runtime user in the video group |
Cause 1: open each camera by serial number
An index is a position in a list the driver rebuilt at boot; a device name is a string the driver prints. Both move. Enumeration order can swap two identical cameras between reboots, and a driver update can change a name by a single hyphen — one rig matched cameras by name for months until a spelling change broke the exact-match lookup.
The serial number is printed on the label and never changes. Read it once at commissioning, store it in your configuration against the camera's role, and open through the SDK's serial selection parameter; GenICam devices carry a serial number feature for the same purpose. Serial-based selection is the method camera vendors document for avoiding selection conflicts, and newer SDK generations add selection by GMSL2 port as a second unambiguous option for a camera that always sits on the same cable.
Test: print the serial of the camera each open call resolves. If it does not match the label of the camera you meant, you have found the conflict. The same discipline is standard on other interfaces — select each camera by serial number on one host and assign cameras to ports reliably apply it to depth and GigE rigs.
Cause 2: free the capture before you open it
A video node serves one subscriber. A viewer left open, a container that never released its nodes, or your own previous run that crashed without closing keeps the device claimed; the next open fails with a busy or access error, not a missing-device error.
Test: stop every capture process, then open. In container deployments, pass the V4L2 media nodes through, not only the video device — passing V4L2 media nodes in Docker shows the mapping. The identical failure exists on GigE, where a second tool cannot open a camera the first holds: GigE camera open fails in a second tool. There the cleaner pattern is to open the camera only while your service subscribes to it, as connect a camera only when subscribed describes.
Cause 3: test every video node with a ten-frame capture
A GMSL capture link exposes more than one V4L2 node per camera — a two-camera stereo rig commonly appears as four nodes — and only some of them carry image frames. Enumeration lists a node whether or not its stream path works, so a half-dead link hides until something pulls frames from it. The middleware then fails at open for a camera that looks perfectly AVAILABLE.
The test takes about a second per node. Capture ten frames from each node with any V4L2 streaming utility:
At a nominal 30 fps each node proves itself in 0.33 s, so a four-node rig sweeps in about 1.3 s; at 60 fps the same sweep takes roughly 0.7 s. Read the result this way: a node that delivers frames is alive. A node that returns zero frames while its sibling on the same camera streams marks the broken half of that camera's link.
Fix the dead half in this order: reseat the coaxial GMSL cable at the camera and at the capture card; swap in a known-good cable from the camera cables range; then recheck the deserializer's device-tree entry for that port — fixing the devicetree chain when a sensor probes but has no video node walks that failure. Where the symptom is stream timeouts and green frames instead of a silent node, GMSL stream timeout and green-frame fixes for embedded hosts covers the deserializer side.
Cause 4: keep the SDK and the GMSL driver matched
The camera middleware and the kernel-side GMSL driver ship as a pair. Bring a rig back after months idle, or update the host OS in between, and you get a new SDK over an old driver: enumeration still works, open fails. Print both versions at every startup and log them next to the frame counts.
Fix: update the SDK and the driver together, from the vendor's own download channels, then reboot and repeat the node sweep. For the access layer under your SDK — GMSL and FPD-Link III camera configuration on embedded boards — GMSL and FPD-Link III camera access configuration for embedded hosts is the deeper reference.
Cause 5: check permissions once, not first
If the node exists but no open succeeds for your user, while a one-off open with root privileges works, the cause is permissions rather than selection. An OS update can change group membership or the rule that assigns nodes to groups. Confirm it exactly that way, as a one-time diagnostic, then put the runtime user into the group that owns the video nodes and make the fix persistent — Linux camera device permissions: video and media node checks has the commands. Do not run production capture as root.
A startup self-check that fails fast
Put the selection rule in code so it cannot regress. The pattern, in pseudocode with example serials:
expected = {"1102451": "left", "1102452": "right"} # label serial: role
found = enumerate_cameras() # your SDK's device list: serial, name, index
missing = sorted(set(expected) - {d["serial"] for d in found})
if missing:
print("Missing serials:", missing)
print("Found serials:", [d["serial"] for d in found])
exit(1) # fail before any open call
for serial in expected:
cam = open_camera(serial=serial) # serial only, never index or name
Every name here is illustrative — your SDK's enumeration and open calls carry their own names, and all of them offer selection by serial. The two decisions that matter survive any API: compare serial sets before the first open, and resolve each camera by serial.
Prevention at the bench
Five habits keep this failure from returning:
- Store label serials against roles in version-controlled configuration; never store indices or device names.
- Assert the serial set at startup and fail with the list of found serials — a missing camera becomes a one-line diagnosis.
- Log the SDK and driver version pair on every boot, and update the two together.
- After any driver or OS update, repeat the ten-frame sweep — about 1.3 s for four nodes — before running the rig.
- Give every capture process one owner: a single service subscribes, everything else waits.
The same rule on GigE and USB3 hosts
None of this is GMSL-specific. GenICam devices — GigE, USB3, Camera Link behind a frame grabber — carry a serial number feature, and the discipline transfers directly: enumerate, match serials against your configuration, open by serial, one owner per device. The USB variant, where two cameras fight over one claim, is diagnosed in two cameras interface claim conflict: diagnose USB access.
If you are building the multi-camera host itself, the parts are standard: GigE area scan cameras over a PoE network card from the frame grabbers range. A two-camera rig needs two independent streams on the host. The MV-GE2002P is a dual-port PoE NIC.
- Interface
- GigE
- Ports
- 2 ports
A four-camera rig needs four. The MV-GE1104 is a 4-port GigE frame grabber.
- Interface
- GigE
- Ports
- 4 ports
Where to go next
For the GigE side of a multi-camera build, start at the accessories finder, which filters frame grabbers and cables by interface and port count. The systems topic page collects the acquisition-failure guides that pair with this one, from camera capture pipeline startup failure: isolate the cause to frame grabber camera configuration not responding: fix the frame grabber host PC. If a rig still fails after all five causes, send the enumeration output and the per-node frame counts through the contact page and we will read them with you.
Questions
Why does my GMSL camera report AVAILABLE but fail at Camera Open?
The AVAILABLE flag tells you the driver enumerated the device descriptor; it says nothing about streaming. Opening demands the full stream path: every V4L2 node for that camera alive, no other process holding them, and a matched SDK and driver pair. With multiple cameras, the most frequent cause is a selection conflict — your code opens by index or name and another camera claims that slot. Print the serial your open call actually resolved and you will usually find the wrong camera or none.
How do I select a camera by serial number instead of index?
Every camera's label carries its serial; store the serials for each role in your configuration at commissioning. At startup, enumerate the devices, compare the serial sets, and open each camera through the SDK's serial selection parameter — GenICam devices carry a serial number feature for the same purpose. Treat index and device name as display information only: enumeration order shifts across reboots, and driver updates rename devices.
Why are there more /dev/video nodes than cameras?
A GMSL capture link exposes several V4L2 nodes per camera: image data on some, auxiliary data on the rest, so two stereo cameras commonly appear as four nodes. Enumeration lists every node whether or not it streams, so a dead node hides until you capture from it. Run a ten-frame capture on each node; any node that returns zero frames while its sibling streams marks a broken half of that camera's link.
Can I select a GMSL camera by its connector port instead?
Newer SDK generations add selection by GMSL2 port, which is unambiguous for a camera that always sits on the same cable. Until your installed SDK offers it, serial number remains the reliable key: the port-to-device mapping can change between boots, while the label serial never does. Check your SDK release notes for port-based selection and move the configuration over once it ships in the version you run.
Do the SDK and the GMSL driver need matching versions?
Yes. The camera middleware and the kernel-side GMSL driver are released as a pair; an updated application over an old driver — or the reverse — passes enumeration and then fails at open. After any OS update or long idle period, print both versions at startup, update both from the vendor's own distribution channels together, then re-run the ten-frame node sweep before running the rig.

