Some USB cameras speak UVC but never say so. Their firmware leaves the USB class fields that identify a video device unset, so Linux enumerates the hardware, prints it in lsusb, and binds no driver at all: no /dev/video node appears and every vision tool on the machine reports that no camera exists. The pattern is common on older USB 2.0 industrial CCD cameras and on rebranded modules, and the fix is a udev rule that teaches the uvcvideo driver the camera's vendor and product IDs at every plug-in.
This guide is for integrators bringing a camera up on a Linux line PC or embedded board. You will diagnose why the node is missing, prove the camera really is UVC with a one-line manual bind, install the rule, confirm frames arrive, and run the bandwidth arithmetic that tells you whether the old camera is still worth keeping. For the rest of the bring-up stack, the systems guides continue where this one stops.
Why does lsusb list my camera but no /dev/video node appear?
Because the kernel found the hardware but no driver claimed it: uvcvideo probes only interfaces whose USB class code says video — class 14, written 0x0e — and your camera's firmware leaves that field unset or vendor-specific, so the probe never runs.
USB drivers match on interface descriptors, and uvcvideo's table matches the video class. A camera whose descriptors report class 0x00 or 0xff never reaches the driver, no matter how UVC-capable its silicon is. Start here:
lsusb
Bus 001 Device 008: ID 1bcf:28c1
Your two hexadecimal values will differ; what matters is that the camera is present. Then run:
lsusb -t
The tree view prints the driver bound to each device, and a camera nobody claimed shows no driver name on its leaf, while dmesg stays quiet about it. That combination — present in lsusb, no driver in lsusb -t, no node — is the signature this guide fixes. If a node exists and only your SDK misses it, read USB camera in lsusb but not detected by the vision SDK instead; the camera is already up and the problem sits one layer higher.
How do you rule out the cable, the port and permissions first?
A camera that flickers in and out of lsusb is a link problem, and a /dev/video node you cannot open is a permissions problem; both are cheaper to eliminate than driver binding, and neither is fixed by this rule.
Swap to a short known-good cable and a different port before anything else: long runs and reels cause intermittent enumeration that looks exactly like a missing driver. If the camera has power but the host still never sees it, work through camera power but not detected: USB link checks after a cable swap. Permissions are the other impostor. Those udev rules change ownership and mode on a node that already exists, which is why udev rules for USB cameras: fix permission denied is a different article from this one — a permission rule cannot grant access to a node that was never created.
Keep one known-good cable on the bench as your reference: the LS-CBL-0219 is a 3 m USB3.0 camera cable rated for drag-chain use.
What does a manual bind prove before you automate it?
Writing the camera's ID pair to the uvcvideo driver's new_id file answers the one open question — is this camera really UVC — because the kernel re-probes matching devices immediately and either creates a node or rejects the probe.
- Read the pair from
lsusb. In this example it is1bcf:28c1; substitute your values everywhere below. - Load the driver if it is not loaded:
lsmod | grep uvcvideo, and if that prints nothing,sudo modprobe uvcvideo. - Teach the driver the pair:
echo 1bcf 28c1 | sudo tee /sys/bus/usb/drivers/uvcvideo/new_id. Mind the separator: lsusb prints a colon, new_id wants a space between the two hex values. - Check the node with
ls /dev/video*, thenlsusb -tagain — the camera's leaf now names uvcvideo. Current kernels create two nodes for one UVC camera, capture and metadata; the capture node is the one to open. - If nothing appeared, unplug and replug once. If
dmesgthen shows the probe being rejected, the descriptors are not UVC and no rule will change that; jump to the failure section below.
What exactly goes into the udev rule?
One line matching the camera's idVendor and idProduct on USB add events and running modprobe plus the new_id write is all the rule needs; udev fires it whenever the camera is added, whether by plug-in or by the replay at power-on.
# /etc/udev/rules.d/80-hidden-uvc-cameras.rules
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1bcf", ATTR{idProduct}=="28c1", RUN+="/bin/sh -c 'modprobe uvcvideo; echo 1bcf 28c1 > /sys/bus/usb/drivers/uvcvideo/new_id'"
Replace both ID values with your pair and keep the two occurrences identical. Add one line per camera model: four cameras on one cell means four lines in the same file. The 80- prefix only orders the rule against other files and can stay as it is. RUN commands execute as root; if your build's udev cannot find modprobe on its PATH, spell out the absolute path, commonly /usr/sbin/modprobe.
How do you install the rules file and reload udev?
Copy the file into /etc/udev/rules.d/, reload the rules, re-run them for hardware that is already connected, then unplug and replug the camera once so the rule fires cleanly after the driver table is ready.
sudo cp 80-hidden-uvc-cameras.rules /etc/udev/rules.d/-
sudo udevadm control --reload-rules— on older distributions,sudo service udev restartdoes the same job. -
sudo udevadm trigger --action=addto replay the rule for devices that never left the machine. - Check
ls /dev/video*. If the node is still missing, reboot once: vendors that ship such rules note that a full restart is sometimes needed, and a reboot removes every ordering question in one stroke.
How do you confirm the camera streams and not just enumerates?
A node is not a picture: point v4l2-ctl at it, list the formats the camera actually offers, pull ten frames to a file, and check that the file size matches the format and the count you asked for.
v4l2-ctl --list-devices
v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=10 --stream-to=/tmp/frames.raw
The size check is where the arithmetic earns its place. A raw YUYV frame at 1280 × 960 carries two bytes per pixel:
If /tmp/frames.raw comes out at 24.6 MB, the pipe works end to end. The same numbers decide the format: USB 2.0 High-Speed signals 480 Mbit/s, which is 60 MB/s on paper, and sustains roughly 35 MB/s of payload once isochronous scheduling and protocol overhead take their share. Fifteen uncompressed frames a second need 2.46 × 15 = 36.9 MB/s — over budget. Ten frames a second need 24.6 MB/s and leave about 30 percent headroom, so cap raw YUYV at 10 fps at that size, or switch the camera to MJPEG and keep the full rate.
From here the neighbours take over: black frames mean UVC format negotiation trouble, a healthy node your application ignores is the /dev/video0 app-side problem, and a camera inside a container needs the V4L2 media nodes passed into Docker, not just /dev/video0.
When does the whole approach fail, and what replaces it?
Three failures end this road: the kernel was built without uvcvideo, the probe rejects the camera because its descriptors are not UVC, and the camera is USB3 Vision or a vendor protocol that was never UVC.
If sudo modprobe uvcvideo answers that the module does not exist, no udev rule can help, because the driver itself is missing from that kernel. Locked-down industrial gateways ship this way; the UVC camera not recognized on an industrial gateway walkthrough covers the first checks, and when the fix has to reach the kernel configuration itself, the kernel rebuild for missing USB UVC support is the level you are working at. On boards you control, choosing UVC-class cameras is what lets you skip driver rebuilds: cameras that advertise the class never need this guide's rule.
A probe rejection in dmesg means the firmware is not UVC where it counts. The legitimate path from there is the manufacturer's own driver or SDK, taken from the maker or one of its distributors — never a third-party copy. And if the camera is USB3 Vision or GigE Vision, it was never a UVC candidate: bring-up runs through a GenICam-based stack plus a permissions rule, which starts at USB3 Vision camera not detected on Linux.
Keep the old camera or replace it with USB3 Vision?
Keep the old camera if one UVC node at up to about 10 fps at megapixel sizes covers the inspection; replace it when you need deterministic triggering, GenICam exposure and gain control, or throughput beyond what USB 2.0 carries.
The deciding numbers sit in the section above: the raw-mode ceiling of the old bus, the 24.6 MB a ten-frame test writes, and the trigger and control features UVC simply does not expose. UVC gives you a node anywhere; USB3 Vision gives you the camera. For the replacement path, a good first candidate: the LS-CMR-0166 is a 12 MP USB3 area scan camera with a 4000 × 3000 resolution and 30 fps.
- Sensor format
- 1/1.7"
- Interface
- USB3
- Resolution
- 12 MP
- Shutter
- Rolling
USB3 Vision is not UVC: the camera enumerates on its own stack, and the Linux work is a permissions rule, not a binding rule. A 4000 × 3000 raw frame is 24 MB, and three of them a second already saturate a USB 2.0 link — which is why that sensor class lives on USB3. Browse the area scan cameras category or the camera finder to compare interfaces and resolutions.
Before you order, five checks:
- Confirm the target kernel ships uvcvideo, or the USB3 Vision stack you plan to use — a camera that binds to nothing on a trimmed kernel wastes the lead time.
- Count cameras per USB controller against the bus budget: two cameras streaming raw share one ceiling.
- For USB3 Vision, put the SDK and its permission rule in the machine image, not in commissioning week.
- Specify a drag-chain-rated cable for anything on a moving mount; the bench spare from earlier tells you what that looks like.
- Prefer cameras whose data sheet states UVC compliance or USB3 Vision outright, so bring-up never needs a hand-written rule.
Next step: run the configurator from the camera step for a matched camera-and-cable set, and if the probe rejects your camera and you want a second opinion on the bring-up, use the contact page to reach the applications team.
The configurator matches a camera, lens, light, light controller and cables to each other, step by step, and lists only parts that fit what you already picked.
Questions
Does adding DRIVER=uvcvideo to a udev rule bind the driver?
No. DRIVER is a match key that udev compares against the driver the kernel has already bound; it cannot assign one. Binding is the kernel's job, which is why the rule works through RUN: it loads uvcvideo and writes the IDs to the driver's new_id file, and the kernel then probes the device. Treating DRIVER as an assignment is silently ignored on device events.
Does the new_id entry survive a reboot?
No. Dynamic IDs live in kernel memory and vanish with the kernel that created them, which is exactly why the udev rule exists. The rule rewrites the pair at every add event, including the synthetic add events udev replays for devices that are already connected when the machine starts. As long as the rules file stays in /etc/udev/rules.d/, a reboot leaves you with a working camera.
Can one rules file cover several camera models?
Yes. Repeat the same pattern once per vendor and product pair inside the same file in /etc/udev/rules.d/. Each line filters on its own ATTR{idVendor} and ATTR{idProduct} values and writes its own pair to new_id. Keep the lines identical in shape so a second camera can be added later by copying one line and changing two values.
The node appears now but frames come out black, so what is next?
That is a format negotiation problem, not a binding problem. List what the camera offers with v4l2-ctl and its --list-formats-ext option, then request one of those formats exactly, including width, height and pixel format; many UVC cameras start in a compressed mode your code does not decode. The fixes are worked through in [USB camera black image: fix UVC format negotiation](learn:usb-camera-black-image-on-linux-fix-uvc-format-negotiation).
Will this bring up a USB3 Vision camera that shows no node?
No. USB3 Vision cameras are not UVC devices; they enumerate normally on a GenICam-based stack and need a udev permissions rule for their device node. If your camera is USB3 Vision, start with [USB3 Vision camera not detected on Linux](learn:usb3-vision-camera-not-detected-on-linux-fix-udev-permissions) instead of forcing uvcvideo onto it.

