You installed a machine-vision SDK on a Linux host, ran its install scripts, and the enumeration tool prints Cameras found: 0. The same camera answers ping from the same terminal, so cable, interface and IP settings are all working. This pattern is almost always one of two causes: the GigE transport layer is not loaded into your session, or a firewall is silently discarding the camera's discovery reply while letting ICMP through. The three tests below run in about ten minutes, ordered so the most likely cause falls first, and each ends in the exact command that fixes it.
Why ping passes while enumeration returns zero
Ping and discovery are different protocols doing different jobs. ping 192.168.10.23 sends ICMP echo to one address you already know, and a reply proves the link, the addressing and the interface. Enumeration asks more of the system: the SDK loads a GenTL producer for GigE, broadcasts a discovery request on UDP port 3956 — the GigE Vision control port — and waits for each camera to answer with its identity. Two independent things must be true before a camera appears: the producer must have loaded before your code started, and the reply must get back through the firewall. Ping proves neither of them. When ping works and the count stays at zero, stop swapping cables and work the software path first; broader background is in Linux GigE Vision camera discovery troubleshooting.
Test 1: is the transport layer registered in this shell?
Linux SDK installers export GENICAM_GENTL64_PATH from a profile script in /etc/profile.d/ or ~/.bashrc. A terminal that was already open when the installer ran never re-reads those scripts, so the variable is missing in exactly the shell you are testing from. Check it:
env | grep -i GENICAM
You want a line like GENICAM_GENTL64_PATH=/opt/<sdk>/lib/64-bit. A 64-bit Python interpreter reads the 64-bit variable; a 32-bit build reads GENICAM_GENTL32_PATH. If the command prints nothing, the fix is a re-login, not a reinstall:
- Log out and back in, or reboot once. The reboot guarantees that no surviving shell carries a pre-install environment.
- For an immediate check without logging out,
sourcethe profile file the installer created, then rerun enumeration in that same shell. - Repeat
env | grep -i GENICAM. The path must print before anything else can work.
If the variable was missing and the camera now enumerates, you are done: there was never a network cause.
Test 2: does the producer file exist where the path points?
GENICAM_GENTL64_PATH holds a colon-separated list of directories, and the GigE producer inside one of them is a .cti file. A path pointing at a directory you moved or renamed enumerates nothing and prints no error. Confirm the file is real:
echo $GENICAM_GENTL64_PATH
ls -l /opt/<sdk>/lib/64-bit
Hold the set-up to this standard: at least one GigE .cti sits in a listed directory, and it carries the execute bit. If it is missing, reinstall the transport-layer part of the SDK instead of editing the variable by hand — the installer places dependent libraries beside the producer. If the file is present and enumeration still finds zero cameras, the software side is sound and the packet path is next.
Test 3: is the firewall eating the discovery reply?
ufw, the default firewall front end on many Linux distributions, denies unsolicited inbound packets. Your discovery request goes out as a broadcast; the camera's reply comes back as inbound UDP from port 3956, which the firewall treats as unsolicited and drops. ICMP echo is handled by a separate rule, which is exactly how you get working ping and zero cameras. The evidence is in the kernel log:
sudo dmesg | grep -i ufw
Blocked UDP lines carrying the camera's address on port 3956 name your cause. One question decides the fix: does the camera have its own interface?
sudo ufw allow in on enp3s0
With your camera interface in place of enp3s0, that single rule is the whole fix on a dedicated link. Streaming ports are negotiated per camera, so chasing port lists on a camera-only interface buys nothing. On a shared corporate interface, scope the rule to the camera:
sudo ufw allow from 192.168.10.23 to any port 3956 proto udp
That covers discovery and control; add the camera's streaming port once you can read it from the control page. For the deeper version of this case, read GigE Vision camera firewall: ping works, discovery fails.
A worked example: one camera, one subnet, two causes
A fresh machine, one GigE area scan camera, one host. The camera interface enp3s0 holds 192.168.10.5/24; the camera is at 192.168.10.23.
Both addresses land on 192.168.10.0/24, so no router is involved and the broadcast address is 192.168.10.255. Now the sequence as it actually runs on a new install:
-
ping -c 2 192.168.10.23returns 2 received, 0 lost. The link is good. - The enumeration script prints
Cameras found: 0. -
env | grep -i GENICAMprints nothing. The installer wrote its export after this terminal started. - Log out and back in. The variable now prints — but the count is still zero. A second cause is stacked on the first.
-
sudo dmesg | grep -i ufwshows blocked UDP from192.168.10.23on port 3956. -
sudo ufw allow in on enp3s0, then rerun the script: one camera, listed with its IP address and MAC.
Two stacked causes on one fresh machine are normal: the install has never had a re-login, and the OS has never had a firewall exception. On a brand-new integration, run both checks before touching any hardware.
Telling the causes apart at a glance
| Evidence | Cause | Fix |
|---|---|---|
env prints no GENICAM path |
Transport layer not loaded in this session | Log out and back in, or reboot once |
Path set, no .cti in the listed directories |
Producer moved or never installed | Reinstall the SDK's transport-layer package |
Path set, .cti present, dmesg shows blocked UDP 3956 |
Firewall dropping the discovery reply | Allow the camera interface, or UDP 3956 from the camera |
| Ping fails as well | Addressing or link, not software | Put host and camera on one subnet, then open by IP |
Run the tests top to bottom; each row takes under a minute once the commands are in your shell history.
When zero cameras is something else
- Ping fails too. The camera may sit at a factory link-local address such as
169.254.1.2while the host interface holds a different subnet. Set the host static inside the camera's address band, or open the camera by its IP address. - The vendor's viewer finds the camera but your code does not. The viewer loads its own producer; walk through GenTL transport layer startup: diagnose discovery failures.
- Cameras appear after a manual rerun but not at boot. That is camera discovery startup contention in multi-camera systems.
- Several cameras, one missing. Give each camera a fixed address per port as covered in assign cameras to ports reliably in a multi-camera system.
Build the next machine so this cannot recur
Give the camera its own interface and power, so corporate firewall policy never touches discovery. A dual-port PoE NIC such as the MV-GE2002P does both:
- Interface
- GigE
- Ports
- 2 ports
For several cameras, a 4-port GigE frame grabber such as the MV-GE1104 keeps each camera on its own port with no switch in between; once they stream together, the GigE multi-camera frame-drop troubleshooting guide is the next thing worth reading. And lock the physical link: a half-seated RJ45 without a locking stud mimics every software cause above. Use a cable with screw locks and a high-flex rating:
Checklist before you blame the hardware
-
env | grep -i GENICAMprints a GENICAM path in the same shell that runs your code. - A GigE
.ctiproducer is present and executable in a listed directory. -
sudo dmesg | grep -i ufwshows no blocked UDP on port 3956 after a discovery attempt. - Ping returns 2 of 2 packets to the camera's address.
- Host and camera share one subnet, so the broadcast reaches the camera directly.
- The vendor's viewer and your own script report the same camera count.
If all six pass and the count is still zero, send the three command outputs to us through the contact page; with those in the message, the answer is usually one reply away. To spec the whole link from camera to cable in one pass, start at the camera step of the system configurator.
Questions
Why does ping reach a camera the SDK cannot find?
Ping is ICMP aimed at one address you already know, so it proves cable, interface and addressing only. Enumeration loads a GenTL producer and broadcasts a request on UDP 3956; the camera's reply arrives as unsolicited inbound UDP, which a deny-by-default firewall drops before your code ever sees it. Stable ping with zero cameras therefore points at the transport layer or the firewall, not the hardware.
Do I need GENICAM_GENTL64_PATH or GENICAM_GENTL32_PATH?
Match the variable to the bitness of the process that enumerates, not of the operating system. A 64-bit Python interpreter or application reads GENICAM_GENTL64_PATH; a 32-bit build reads GENICAM_GENTL32_PATH. On a 64-bit host running 64-bit Python, checking the 64-bit variable with env is enough; a 32-bit container or virtual machine needs its own export inside that environment.
Is logging out enough, or do I have to reboot?
Logging out and back in re-reads the profile scripts that export the GenICam path, and that alone clears a missing variable. Reboot once when several components were installed in one session, or when you cannot tell which shell inherited which environment; it is the only way to guarantee a clean baseline. Firewall rules changed with ufw apply immediately, so they never need the reboot.
Which firewall ports does GigE Vision need open?
Discovery and control run on UDP 3956. Image streaming uses GVSP on UDP ports the camera and host negotiate at start-up, so one fixed port is never enough for a full session. On an interface dedicated to cameras, allow the whole interface. On a shared interface, allow UDP 3956 from the camera's address plus its negotiated streaming ports, or all UDP from that address.
Can a bad cable cause zero cameras found?
Almost never when ping is clean. A cable problem that matters pulls the link down, and dmesg then shows the interface cycling up and down, or ping loses packets intermittently instead of returning a steady two-for-two. With a stable reply and no interface messages in the kernel log, keep working the transport layer and firewall path rather than replacing hardware.

