The camera lists fine in enumeration, then the open call dies instantly with 'Filter could not be found' — one machine-vision library prints the same failure as error -1074396020. Nothing is wrong with the camera. The open call does not search for hardware; it looks the name you pass up in the device table the enumeration call just built, and it compares that string byte for byte. This page is for engineers wiring a USB camera into a vision program: it explains why the name is a lookup key, ranks six causes from most to least common, gives a byte-level test that settles the question in one run, and closes with the fix, the prevention habits and the hardware checks that keep the error from coming back.
What 'Filter could not be found' means
Enumeration and open are separate calls, and only the first one touches hardware. The enumerate call walks the system's device table — on Windows, a DirectShow-based toolkit walks the capture-device moniker list, where each moniker is a COM object that stands in for one capture device, as the DirectShow capture-device documentation describes — and returns a name for each entry. The open or init call enumerates nothing: it takes the name you hand it and asks the system for the device that matches that name exactly.
The error therefore says one precise thing: the string you passed is not in the table as it stands right now. Either the string was never a copy of what enumeration produced, or the table changed after you read it. Every cause below falls into one of those two buckets.
The instant failure is itself evidence. A mismatch dies before any frame is requested and before any timeout can expire, so an error at open — with a camera that listed moments earlier — points at the string, not at a hung device.
The exact-match rule, with the arithmetic
The rule: the string you open with must equal, byte for byte, a string that enumeration returned on the same machine, in the same session. Not similar — equal. Case counts, spaces count, invisible characters count, and matching length proves nothing.
names = enumerate_cameras() # illustrative wrapper; returns a list of strings
# names[0] = 'USB Camera' # 10 bytes, exactly as the OS returned it
# names[1] = 'USB Camera' # a second, identical unit
open_camera('Usb Camera') # fails: 10 bytes, different bytes (0x73 vs 0x53)
open_camera('USB Camera ') # fails: 11 bytes, trailing space
open_camera(names[0]) # passes: byte-for-byte copy of the enumerate output
Work the arithmetic on the two failures. 'Usb Camera' and 'USB Camera' both measure 10 bytes, so a length check alone passes while the open still fails — the lowercase s, 0x73, is not the uppercase S, 0x53. 'USB Camera ' measures 11 bytes, and the length check catches it at once. The test is therefore two steps: compare lengths first, then compare the bytes.
Text pasted from a PDF or a slide deck is the classic carrier of the non-breaking space: it prints like a space but encodes as 2 bytes in UTF-8, so the length check exposes it where the eye cannot.
Six causes, ranked from most to least common
Test top down; the first cause takes two minutes to confirm or clear.
- A hand-typed, hand-trimmed or rebuilt name. The string was copied into a constant, 'corrected', or reassembled from device parts. Test: print the enumerated strings and the string you open with, each with its byte length. Any difference settles it.
- A name saved on another machine, port or OS language. Device names can carry localized text — the friendly name comes from the driver's own strings, which the OS translates — so a name recorded on an English install can miss on a German or Japanese one. Test: enumerate on the target machine and compare its output against the stored string.
- A stale list. The camera was re-plugged or moved to another port or hub, or the bus re-enumerated after sleep or resume; the instance path your string encodes no longer exists. Test: re-enumerate immediately before the failing open and diff the two lists.
- Two identical cameras that swapped. Identical units share a display name; the device path or instance string behind each entry is what differs, and an index into an unsorted list takes whichever unit answered first. Test: unplug one unit and watch which entry disappears — then address them the stable way described in two identical USB cameras: open one by port.
- A camera that left the bus between listing and opening. A tired cable or an over-committed hub drops the device; enumeration succeeded, the device is gone by open time. Test: re-enumerate — if the entry vanished, fix the bus, not the string.
- A camera that was never in this list. A USB3 Vision camera does not appear in the webcam (UVC) enumeration at all; it is covered in its own section below. Test: confirm which stack produced the list you are matching against.
Fix: enumerate, select and open in one pass
- Enumerate at program start, and again after every re-plug, resume or driver reload. Keep the whole entry per device: display name plus device path or instance string, whichever your toolkit returns.
- Log one line per device: byte length, then the raw string. That log is the evidence that settles every later dispute.
- Select the camera by a stable key. Match on the serial number if the entry carries one; otherwise sort the entries by device path and take your own fixed position. An index into an unsorted list is not a selection.
- Copy the chosen name into the open call untouched: no trimming, no reformatting, no reassembly, no constants.
- Open immediately, in the same pass as the enumeration. The shorter the gap, the smaller the window in which a re-enumeration can invalidate the table.
- Prove the result instead of hoping: assert that the string you opened with is byte-equal to an entry in the list you just read. If an exact copy still fails, the table changed under you — re-enumerate, log again, and the missing entry shows you when.
entries = enumerate_cameras_full() # illustrative; returns the full entries
for e in entries:
log(len(e.name), e.name) # one line per device: length + raw string
my_serial = 'A10234' # str; your stable key, read off the label
target = pick_by_serial(entries, my_serial) # illustrative selector
assert target.name in [x.name for x in entries] # the test: an exact copy exists
open_camera(target.name)
One more habit belongs here: open once and keep the session. Programs that open and close the camera every cycle leak handles over time; the mechanism and the fix are in camera open/close cycles leak handles.
When the string is right and the bus is not
If a fresh, byte-exact name still fails at open, stop editing strings and look at the bus. A camera that repeatedly drops and re-enumerates builds a new table each time, and a new table can carry a new name — which is exactly why the string 'worked yesterday'. The physical causes, in order: cable fatigue at a moving joint, a worn connector latch, and a hub whose power budget is spent.
The budgets are in the USB specification. A USB 3.0 port supplies up to 900 mA at 5 V nominal (0.9 A × 5 V = 4.5 W per device), and a USB 2.0 port stops at 500 mA, 2.5 W. A camera drawing close to its allowance behind unpowered hub ports spends that budget before the first frame, and the bus answers by dropping and re-listing the device.
Most intermittent-enumeration cases trace to the camera data cables first. On a moving axis, fit a cable built for the duty: the LS-CBL-0219 is a 3 m USB3.0 camera cable with high-flex, drag-chain construction.
The same hardware fault wears a different costume on each stack. On a Linux/V4L2 host the vanished device ends as error 19, no such device, at the read call — the VIDIOC_DQBUF error 19 walkthrough traces that end of the chain. If the camera disappears mid-run rather than at open, stale-frame detection catches it from the frames you already hold. And when several cameras share one host, the bandwidth and power budget method is the arithmetic that keeps every unit enumerated.
A machine-vision camera never matches a webcam name
Two device classes both say 'USB camera' and share no table. Webcams enumerate through the UVC/DirectShow stack — the list your open-by-name code is most likely reading. Machine-vision USB3 cameras run the USB3 Vision standard: their own transport and their own device discovery, exposed through the camera SDK with serial-number addressing. A USB3 Vision camera never appears in the UVC list, so no amount of string hygiene makes a webcam-style open find one.
If the device you open is an industrial camera, enumerate through its SDK, not through the webcam stack. Both of these are USB3 units with SDK access:
- Sensor format
- 1/1.7"
- Interface
- USB3
- Resolution
- 12 MP
- Shutter
- Rolling
- Sensor format
- 1/1.8"
- Lens mount
- C-mount
- Interface
- USB3
- Resolution
- 6-10 MP
The first streams 4000 × 3000 frames at 30 fps over USB3. The second is a 6 MP mono unit with a C-mount and a 1/1.8" sensor. The same enumerate-select-open discipline applies to them and to board-level cameras built into your own housing; only the SDK's naming differs.
One related trap: a camera that enumerates under a generic name and refuses every exact-match open usually has a broken device entry, not a broken string. USB camera shows a generic UVC name walks that reinstall.
Prevention checklist
- Store a stable key, never the display name: serial number or fixed physical port. The name is machine-, port- and language-specific; the key is not.
- Enumerate fresh at every start and open in the same pass. A re-enumeration in between invalidates the table you matched against.
- Log byte length plus raw string for every enumerated device. The length-and-byte pair turns an invisible mismatch into a visible line.
- Sort entries by a stable key before indexing, so identical units cannot swap between boots.
- Feed each camera from a port or powered hub that meets the USB 3.0 budget of 900 mA at 5 V nominal. Under-power reads downstream as intermittent enumeration, and re-enumeration reads as stale names.
- Fit drag-chain-rated cable on every moving axis; flex fatigue is the most common physical cause of repeated re-enumeration.
- Before shipping, run the enumeration once on the target machine and OS language. The list that matched on the bench does not travel.
More field faults from this family are collected on the machine vision systems topic page.
The decision
Read the failure by timing. An error the instant you open, with the camera still listed, is a string problem: pass the enumerate output straight through and let the byte test prove it. A byte-exact fresh string that still fails is a bus problem: cable, connector, hub power. A camera that never appears in the list at all is a stack problem: enumerate through that camera's own SDK.
If you are standing the hardware side up, the USB3 area scan cameras category and the camera finder filter by interface, resolution and shutter, and the camera configurator pairs the camera with a matched cable in a few steps. For an open error that resists this sequence, send a message through the contact page with your enumeration log attached — the log is the first thing that settles the question.
Questions
Why does the camera open in another program but fail in mine with 'Filter could not be found'?
The other program enumerates at launch and opens the string it just received; yours opens a name that was typed in or read from a saved setting, and that string no longer matches byte for byte. Also close other capture software before testing: many cameras serve one stream at a time, and a busy device fails at open in ways that mimic a name problem.
Does the camera name change when I move it to a different USB port?
Usually the display name stays the same and the device path behind it changes, because the path encodes where the camera was found in the USB topology. A stored full string breaks on the new port, and two ports can swap identical cameras. Store the serial number or a fixed physical port, and rebuild the open name from a fresh enumeration every run.
Two identical cameras enumerate with the same name — how do I open one of them specifically?
Sort on what differs, not on what matches. Pull the full entries, not just display names: the device path or instance string behind each entry carries the USB serial or the port, so sorting on it gives a stable order. Select by that order, open, then confirm with a test frame — block one camera's view and check which one went dark.
Why does the same code open the camera on my bench but fail on the customer's machine?
The customer's machine has a different USB topology and often a different OS language, so its device table carries different strings — localized drivers translate friendly names. A name constant that matched your bench has no reason to match anywhere else. Ship a startup line that prints every enumerated name with its byte length, and match by serial number or fixed port instead of a stored string.


