System designTroubleshooting

libcamera commands not found after an OS update: what changed

Bash returns command not found for libcamera-still after a Bookworm update. The tools were renamed rpicam-* and the old symlinks removed; here is the fix.

LumaSpec Vision10 min read Share on LinkedIn

On this page 9 sections
  1. 01Why does libcamera-still fail with command not found after a Bookworm update?
  2. 02How do you prove the camera hardware is fine in one command?
  3. 03Which commands changed from libcamera-* to rpicam-*?
  4. 04How do you fix scripts that call libcamera-still and libcamera-vid?
  5. 05How do you recreate the libcamera symlinks for legacy software?
  6. 06When is 'command not found' actually a camera or driver problem?
  7. 07How do you keep a capture build stable across OS updates?
  8. 08When does a DIY board-camera stack stop making sense?
  9. 09Questions

You updated to the current Bookworm generation of your OS, typed the capture command that has worked for months, and the shell replied: command not found. Nothing is wrong with the camera. Starting in the 2025 release cycle, the camera package renamed every libcamera-* tool to rpicam-* and removed the compatibility links, which breaks every script, tutorial and README that still calls the old names. The steps below walk the fault in the order you meet it: prove the camera still works in one command, map every old name to its new one, fix your own scripts in minutes, and restore the old names for legacy software you cannot edit. They end with the cases where command not found really does hide a driver or hardware fault, and with the point at which a DIY board-camera build stops being worth maintaining on a production line.

Why does libcamera-still fail with command not found after a Bookworm update?

A 'command not found' after a Bookworm update is almost always the tool rename, not a camera fault: the tools moved from libcamera-* to rpicam-* in the 2023 transition, and the 2025 release removed the symlinks, so the shell finds no executable called libcamera-still.

The error text comes from bash itself. It searches the directories in PATH for an executable with that exact name, finds none, prints the message and exits with status 127. The driver, the device-tree overlay and the sensor are never loaded, which is also why a different camera board revision cannot produce this message.

Rank the causes in the order you should test them:

  1. The update renamed the tools. The application suite moved from libcamera-* to rpicam-* — announced in November 2023 — and the compatibility symlinks that kept the old names resolving were removed across the 2025 release cycle. This sits behind nearly every post-update report.
  2. Third-party code still calls the old names. Same root cause, different entry point: a tutorial, an installer or a closed binary that predates the rename.
  3. The camera application package is absent. If rpicam-hello also returns command not found, rpicam-apps is not installed on the image.
  4. A PATH problem. Rare on stock images; one command settles it.

Confirm the diagnosis in five seconds:

$ libcamera-still -o test.jpg
bash: libcamera-still: command not found
$ command -v rpicam-hello
/usr/bin/rpicam-hello

The new executable exists; the old name does not. Diagnosis settled.

How do you prove the camera hardware is fine in one command?

Run rpicam-hello: if a live preview window opens, the sensor, the camera interface and the driver stack all work, and the whole fault reduces to command names.

On a machine with a display, the preview opens and closing the window ends the test. Headless, capture a still and weigh the file:

$ rpicam-still -o test.jpg
$ ls -l test.jpg

A file with a real byte count proves the whole chain: sensor readout, driver, encoder, file write. A 0-byte file means the name resolved and the capture failed, which is a different fault with its own ladder of tests. The video path behaves identically: rpicam-vid -t 5000 -o test.h264 records for the timeout given in milliseconds, so 5000 ms ÷ 1000 = 5 s of H.264 — the same duration the old name produced with the same argument.

Budget one minute here. Once this test passes, stop re-seating the module and go fix the names.

Which commands changed from libcamera-* to rpicam-*?

Every tool keeps its job and changes only its prefix: libcamera-hello becomes rpicam-hello, libcamera-still becomes rpicam-still, libcamera-vid becomes rpicam-vid, and the same one-word rule renames libcamera-raw and libcamera-jpeg.

Old name New name Job
libcamera-hello rpicam-hello live preview, first health check
libcamera-still rpicam-still full-resolution still capture
libcamera-jpeg rpicam-jpeg fast JPEG capture
libcamera-vid rpicam-vid video capture to H.264
libcamera-raw rpicam-raw raw frames straight off the sensor

These five cover nearly every script you will meet. Options carry across unchanged: -o names the output file and -t sets the timeout in milliseconds, so rpicam-still -o test.jpg and rpicam-vid -t 5000 -o test.h264 behave like their old-name equivalents, and each tool's --help lists the rest. The tools are the renamed application suite, not a rewrite.

The timeline explains why some machines broke and others did not. The renaming was announced in November 2023; the compatibility symlinks kept old-name calls working through the Bookworm handover; removal rolled out across the 2025 release cycle. Both spellings refer to the same tools.

How do you fix scripts that call libcamera-still and libcamera-vid?

Edit the call sites: swapping the libcamera- prefix for rpicam- carries every argument over unchanged, so libcamera-vid -t 5000 -o test.h264 becomes rpicam-vid -t 5000 -o test.h264 and still records exactly 5 seconds.

For a script you own, this is a find-and-replace. List the call sites, rename them, and verify the listing comes back empty:

$ grep -n libcamera- capture.sh
37:libcamera-still -o /tmp/part.jpg
52:libcamera-vid -t 5000 -o /tmp/part.h264
$ sed -i 's/libcamera-/rpicam-/g' capture.sh
$ grep -n libcamera- capture.sh

Keep the replacement scoped to files where libcamera- appears only as command names, which the grep listing shows in seconds. A typical capture script carries two to five call sites, so the edit costs minutes and needs no administrator rights.

The exit status doubles as a regression test. Before the fix, a failed run exits 127, bash's code for a name it cannot resolve. After it, the same script should exit 0 on success; any other code means the commands now run and the fault has moved downstream into arguments or capture state.

The pattern reaches beyond shell scripts: an update that renames things breaks configuration the same way, as ROS camera launch parameter not supported: fix renamed settings shows for renamed camera parameters.

For legacy software you cannot edit, recreate the mapping in /usr/bin: one ln -s line per command turns /usr/bin/libcamera-still into a link to /usr/bin/rpicam-still, and the old call works again untouched.

Closed binaries and installed applications still expect the old path names, so recreate what the removed links provided:

$ sudo ln -s /usr/bin/rpicam-hello /usr/bin/libcamera-hello
$ sudo ln -s /usr/bin/rpicam-still /usr/bin/libcamera-still
$ sudo ln -s /usr/bin/rpicam-jpeg /usr/bin/libcamera-jpeg
$ sudo ln -s /usr/bin/rpicam-vid /usr/bin/libcamera-vid
$ sudo ln -s /usr/bin/rpicam-raw /usr/bin/libcamera-raw
$ command -v libcamera-still
/usr/bin/libcamera-still

sudo is required because /usr/bin belongs to root, and the final command -v line is the proof: it prints the path where bash now resolves the old name. Run the block once per machine, ideally from your setup script, so a rebuilt image receives it automatically.

This restores the exact compatibility mapping the previous release maintained; no driver or configuration setting changes.

When is 'command not found' actually a camera or driver problem?

A genuine camera fault never reports command not found: that message comes from the shell's executable lookup, before any driver, overlay or sensor is touched, while real faults show up as no-frame errors, corrupted images or missing devices.

Work the ladder from the top:

  1. rpicam-hello itself is command not found. The application package is missing; install rpicam-apps with your distribution's package manager and retest. This is the common second failure on minimal or custom images.
  2. The tool runs but no preview or frame appears. Name lookup and the driver stack are separate layers, and a missing or mismatched device-tree overlay is the usual suspect on embedded boards — camera driver device tree mismatch: diagnose missing DTBs.
  3. Frames error out or arrive unreliably. Configuration mismatches produce no-frame errors, not shell messages — camera configuration revision mismatch: fix no-frame errors.
  4. The preview works but the image is damaged. Corrupted frames point at format or wiring, not names — board level camera image corrupted: check format and wiring.
  5. The capture works but other software cannot see the camera. That is the driver layer between hardware and application — vision software can't find your camera: the missing driver layer.

A cousin error names a missing property instead of a missing command, and the habit that settles both is identical: ask which layer is reporting the absence before touching hardware. Camera exposure property not found: check the source object runs the same diagnosis for SDK calls.

How do you keep a capture build stable across OS updates?

Make the new rpicam-* names your default and treat the symlinks as a bridge: renamed scripts survive every future update untouched, while hand-made links must be re-checked after any upgrade that touches the camera package.

  • Rename every script you maintain to the rpicam-* names. This is the only fix no future update can undo.
  • Keep the five symlink lines in a setup script for legacy binaries, and re-run it after any upgrade that touches the camera package.
  • Smoke-test after every update: rpicam-still -o test.jpg, then ls -l test.jpg. A lit scene typically yields a JPEG in the hundreds of kilobytes; 0 bytes means the names resolve but the capture chain is broken.
  • Record the rpicam-apps version you validated. When a machine behaves differently after maintenance, the first question is which package version it runs.
  • Freeze validated lines. Hold the camera package with your distribution's hold mechanism and schedule the update with the next validation window.

Two minutes of smoke test after an update beats a shift of rejects. Failures that start with an update form a whole family; the systems topic page collects the ones we write up.

When does a DIY board-camera stack stop making sense?

If a general-purpose board-camera stack keeps costing days like this one, move the production side to cameras that speak GigE Vision or USB3 Vision, because those interfaces bring a supported driver stack of their own and never touch the OS image's camera command package.

The purchase is not the cost; the re-validation is. Every OS generation can rename tools, move drivers or change overlays, and each lands on your production calendar. A camera with a standard machine-vision interface sidesteps that feed: GigE Vision cameras travel over Ethernet, USB3 Vision cameras over USB3, and both enumerate through their supported driver stack. The same compact mechanical formats exist in that world, so the optics you chose often transfer directly:

Board-level camerasHikrobot MV-CB016-10GM-M-W 1.6 MP GigE board-level camera, IMX296, Mono, M12 lens mount, WTB GigE portMV-CB016-10GM-M-W
Sensor format
1/2.9"
Lens mount
M12
$559.00View part
Board-level cameras6.3 MP board-level camera, IMX178, 1/1.8" rolling shutter, 18 fps (LS-BCM-0020)LS-BCM-0020
Sensor format
1/1.8"
Lens mount
CS-mount
$290.00View part
Board-level cameras3.1 MP USB3 board-level camera, IMX252, 1/1.8" global shutter, 120 fps (LS-BCM-0003)LS-BCM-0003
Sensor format
1/1.8"
Lens mount
C-mount
$690.00View part

The MV-CB016-10GM-M-W is a 1.6 MP mono board-level camera with an IMX296 sensor, a global shutter and an M12 mount on GigE. The LS-BCM-0020 captures 18 fps at 6.3 MP over GigE with an IMX178 sensor in a 1/1.8" format behind a CS-mount. The LS-BCM-0003 reaches 120 fps at 3.1 MP over USB3 with a global-shutter IMX252 sensor.

On the host side, vision controllers replace the repurposed general-purpose board with hardware meant to run this stack for years: the MV-VC2140-128G40-1T pairs an Intel N-series processor with 8 GB of memory, a 128 GB SSD plus a 1 TB HDD, 3-4 LAN ports, two USB 3 ports and four built-in light channels for strobing.

Vision controllersHikrobot MV-VC2140-128G40-1T VC2100 Vision Controller, N97, 8GB+128G SSD+ 1THDDMV-VC2140-128G40-1T
LAN ports
3-4 LAN ports
USB 3 ports
2 USB 3 ports
Light outputs
4 built-in channels
Memory
8 GB
$1,679.00View partBuild a system with it

The decision rule: if the camera watches a production process, pay once for a standard interface and a maintained host; if it watches a bench experiment, keep the board and apply the fixes above. Browse the board-level cameras category or the camera finder, or take your resolution and interface requirements straight into the camera configurator.

Questions

Does the rename affect the libcamera library and code that calls it directly?

No. The 2023 renaming covered the command-line applications and their package names, which moved to the rpicam prefix. The libcamera library keeps its name and its application interface, so programs that link the library or reach it through a language binding are untouched by this change. Only calls that shell out to the old executable names break.

Why did the camera board I received look different from the listing photos?

Vendors revise camera boards periodically and the photos on a listing often lag the hardware, so a different marking alone is not a fault. More to the point, no board revision can produce command not found: the shell raises that error before any camera hardware is addressed. Compare documentation and pinouts rather than photographs when a revision worries you.

Do I need to re-enable or reinstall the camera after this update?

No. The change is confined to executable names: enablement settings, overlays and driver modules carry over, which is why a single successful rpicam-hello run settles the question. Re-running configuration steps and re-seating the module costs time without touching the failure. Go straight to the renamed commands, or recreate the symlinks if legacy software owns the call sites.

Will a future OS release bring the libcamera command names back?

Plan on no. The old names existed only as compatibility links: announced alongside the 2023 renaming, kept through the Bookworm handover, and removed in the 2025 release cycle. Treat them as gone. Maintain your own scripts on the rpicam names, and reserve recreated links for binaries you genuinely cannot change.

Can the old and new command names work side by side?

Yes. The rpicam-* names resolve on their own once the camera package is installed, and recreated symlinks add the libcamera-* names next to them. The two coexist because the links simply point at the rpicam executables, and deleting a link later returns the system to the stock state without uninstalling anything.