OpenFollow Preview

Manual / Help

Troubleshooting

Most faults come down to the service, the logs, or the network – check them in that order. Run First-look diagnostics below to cover all three, then jump to your symptom.

If the web UI is reachable, start with Diagnostics in the Overview tab. The summary cards point at the sick subsystem, and the Download diagnostics bundle button packages everything for a report.

Start here

First-look diagnostics

Run these on the Pi over SSH (ssh openfollow@<pi-ip> – see Quick Start if you're not sure how). They check, watch, and restart the OpenFollow background service:

# Is the service healthy? Look for "active (running)" in green.
sudo systemctl status openfollow

# Watch the live log – useful while reproducing a problem. Press Ctrl-C to stop.
sudo journalctl -u openfollow -f

# Restart it (fixes most "stuck since boot" symptoms).
sudo systemctl restart openfollow

sudo runs the command with administrator rights and may ask for the Pi password. If status shows failed or activating instead of active (running), the live log is where the reason will be.

If you're working inside the OpenFollow source folder on the Pi, these shortcuts do the same three things:

task status
task logs
task restart

Startup & display

Black screen after flashing the image

A freshly flashed station runs one-time setup on its first boot before the Operator Screen appears. Give it a minute before deciding it's stuck.

  1. Wait through the first boot. The first boot expands the station's storage and waits for the network, so the display can stay dark for up to three minutes. Power-cycle once and let it sit.
  2. Try the other HDMI port and a different cable. On a Pi 5 the output nearest the power connector is the first one. Reseat the cable; a marginal cable, an adapter, or a display that won't accept 1080p60 can stay black.
  3. Use the official 27 W USB-C supply. An under-powered Pi 5 can leave the display dark.
  4. Did the OpenFollow splash logo appear? It tells you where to look next:
    • Splash, then the Operator Screen with a black video area – the app is running, and this is a video-source problem. See No video / black image below.
    • Nothing at all, no splash and no Operator Screen – the service isn't starting. SSH in and run First-look diagnostics: if status shows failed or activating instead of active (running), the live log holds the reason.
  5. Can you reach the Web UI from a browser? If you can, the app is healthy and the fault is the display path itself – stay on the HDMI port, cable, and monitor.
  6. Attached a keyboard and the screen is a text prompt? If the black screen turns out to be a (initramfs) rescue shell rather than graphics, the bootloader couldn't find the root filesystem – usually an older Pi 5 bootloader. Update the bootloader and reboot:
    • If you can reach a shell or SSH into the station, run sudo rpi-eeprom-update -a then sudo reboot.
    • If it won't boot at all, recover from another computer with Raspberry Pi Imager → Choose OS → Misc utility images → Bootloader / EEPROM recovery. Pick the Pi 5 boot device you use (SD card, or NVMe / USB), flash it to a spare SD card, and boot the station once from that card until the screen turns green. Then power off, remove the card, and boot the OpenFollow card again.

No video / black image

The Operator Screen and overlays are up, but the video area is black. If the whole screen is black with no overlays, that's a boot problem instead – see Black screen after flashing the image.

  1. Confirm the source URL or device. Test with ffplay or gst-launch-1.0 on a workstation:
    ffplay -fflags nobuffer rtsp://<cam-ip>:554/stream/main
  2. Check connection status on the on-screen overlay (or Camera & Grid → Video Source).
  3. NDI® 1 2 source not visible? Run gst-inspect-1.0 ndisrc on the Pi. If the plugin isn’t found, the GStreamer NDI® plugin isn’t installed – see Installing NDI®.
  4. Pi camera not detected? Check libcamera-hello --list-cameras; confirm the camera is enabled in /boot/firmware/config.txt.

Network & Web UI

Web UI is unreachable

  1. Is the service running? sudo systemctl status openfollow. If not, start it and check the journal for the failure.
  2. Is the Pi on the right network? ip a; verify the IP address you’re browsing to.
  3. Local sanity check. From the Pi: curl -I http://127.0.0.1/. A 200 means the server is up.
  4. Firewall. If you’ve enabled ufw or another host firewall, allow whichever Web UI port you’re hitting – 80, 8080, or 2010.

Web UI is on :8080 / :2010, or diagnostics is partial

OpenFollow doesn't have permission to bind the web port, and the full diagnostics bundle (USB topology, mount points, throttling flags, complete interface info) needs elevated access too. A packaged install – the image or the .deb – sets both up automatically. If you see a fallback port or a partial bundle, the service isn't running from the package; reinstall OpenFollow (see Installation) so it runs with the privileges it needs.

Station reports 127.0.0.1, peers don't discover

OpenFollow started before the network had an address – typically a fresh boot where the network came up late – so it stayed on loopback (127.0.0.1). Restart it once networking is up: sudo systemctl restart openfollow. If it repeats on every boot, give the Pi a wired link or a faster-associating network so an address is ready before the service starts.

Tracking, calibration & input

Markers drift or jitter

  • Drift over a single show: the camera was bumped, or the lens auto-focused / auto-zoomed mid-show. Lock the camera mount, disable auto-focus and auto-zoom on the camera, then re-run the calibration wizard. See When to recalibrate.
  • Jitter that gets worse with height: a small calibration error grows the further a marker sits above the grid plane, so it reads as wobble overhead. Tighten the solve: re-pin the corners accurately in wizard step 6 and re-check the camera Pos Z, Pitch, and FOV, then verify on stage with a tape measure.
  • Jitter from the gamepad: raise the stick deadzone in Input → Gamepad (Axis deadzone, default 0.15).
  • Jitter only on OSC-driven markers: the incoming position stream is noisy or losing packets. Smooth or rate-limit it at the sender and check the link for loss.

Calibration won’t solve

Wizard step 6 (Corner Pinning) shows red corners and refuses to compute. The wizard rejects corners that cross over or enclose too small an area. Work through these, then press Reset Corners and re-pin:

  1. Camera Position is too far off (step 4). A bad starting point stops the solve. Go back to step 4 and re-check Pos Z and Pitch – Pitch must be negative (camera looking down).
  2. The marked rectangle is the wrong size. Re-measure it on stage; width and depth must match the figures you typed in step 2.
  3. The marked rectangle isn’t square. Measure both diagonals – they must be equal. If they aren’t, re-tape the corners to true 90°.
  4. Corners pinned out of order. Drag each handle to its matching stage corner without crossing the shape over itself.

Full walkthrough: Camera & Grid Calibration → Corner Pinning.

Following too far upstage or downstage

The spot lands up- or downstage of the performer, and operators end up fudging the marker's height to drag it back on. Height is the wrong lever. Check these in order:

  1. Confirm every system shares the same origin. OpenFollow's Reference Point (0, 0, 0) must be the same physical spot, axis directions, and units as the zero point in every console, visualiser, and media server that uses its data. If one system's origin sits up- or downstage of OpenFollow's, every position carries that offset. See Core Concepts → The Reference Point.
  2. Check the camera is in a sensible position. A low, shallow angle flattens depth along the sightline, so a small steering error reads as a big up/downstage miss – which is what tempts operators to compensate with height. Aim for a higher, steeper view of the stage.
  3. Plan the placement with the calculator. Use Positioning the Camera to find a spot whose field of view covers the whole stage at a workable angle, then move the camera to match.
  4. Check image quality. A soft, low-resolution, or laggy picture makes the performer's feet hard to place, and depth keys off the feet. Raise the camera resolution and bitrate, and cut latency.
  5. Ask the operators whether they can see the performer clearly. If the stage lighting (low light, haze, backlight, blackouts) is hiding people, no angle will help. Try a more light-sensitive camera, or a model with IR / night-vision for dark scenes.

Gamepad not detected or buttons are wrong

  • Wrong input mode. The controller must be in XInput mode. A pad in DirectInput or a console profile shows up with no sticks, swapped buttons, or not at all. Check your controller's manual for the mode switch / button combo and set XInput, then replug.
  • Buttons mislabelled. Once in XInput, run the button detection wizard to relearn the layout.
  • Not seen at all. Use a USB-wired connection – wireless / Bluetooth isn't supported for show work.

Output & show control

PSN not received by the console

Almost always a multicast issue.

  1. Same subnet? OpenFollow and the console must share a VLAN.
  2. Is OpenFollow sending? On the Pi: sudo tcpdump -ni any host 236.10.10.10. You should see packets at 60 fps.
  3. Does the console see them? On a Linux workstation on the same VLAN as the console: sudo tcpdump -ni any host 236.10.10.10. If you see them on the Pi but not here, the switch is dropping multicast.
  4. Managed switches. Enable IGMP snooping with a querier on the relevant VLAN. See Networking & Security.
  5. Multi-NIC host. If the Pi has more than one network interface (Wi-Fi + Ethernet), set PSN Network Interface to the correct IP in Output → PSN Output. Leaving it on Auto pins TX to the host's primary outbound IPv4, which is usually right but not always.

OSC output isn’t firing

Most diagnostic answers live on the transmitter's own Diagnostics tab – see OSC Transmitters → Diagnostics. Common skip reasons:

  1. Open the transmitter's Diagnostics tab. The ring buffer shows the last ~100 send / skip events with the rendered address, args, and (for skips) the reason.
  2. Skipped with "no default marker configured"? The message uses [x] / [y] / [z] / [markerid] (or any other default-marker placeholder) but the transmitter has no Default markers. The web editor highlights the offending label in red and gates the Enabled toggle until you either set a default or rewrite the placeholder using the explicit-marker form ([x:N]).
  3. Skipped with "default marker N not registered"? The marker ID isn't in this station's controlled markers. Add it under Markers & Zones → Marker Control & Visibility.
  4. Skipped with an unresolved [z.frac]? The fractional height placeholder ([z.frac]) needs the grid's Max Height to normalise into ±1. Set a sensible upper bound (truss height, e.g. 6 m) under Camera & Grid → Grid → Max Height. Until then, the transmitter skips with the actionable hint.
  5. Sending but not received? Check destination IP / port. For TCP transmitters, confirm Framing (SLIP vs Length-prefix) matches the receiver.
  6. TCP transmitter stuck in backoff? The receiver is refusing or actively closing the connection. The status panel shows the current backoff window (0.25 s → 0.5 s → 1 s → 2 s → 5 s, holding at 5 s). Check the receiver's port is open and reachable; a successful connect resets the backoff.
  7. Stream output is silent. If Send only on change is on, the transmitter only fires when the transmitter's default marker has moved more than the per-axis min change threshold since the last send. The gate watches the default marker even if the message uses [x:3]. Move the marker or switch to Send always.
  8. Quoted args rejected at save? Unclosed quotes surface a 400 with one wording. Balance the quotes, then save again. /cue/start "Cue 12" 1.0 sends two args; /cue/start "Cue 12 1.0 rejects.
  9. Use Test send. Fires the transmitter once with current data, independent of the enable toggle and trigger.

OSC input isn’t accepted

  1. Allowlist. If Allowed sender IPs is set, your sender’s IP must be in it. If not, check the journal:
    sudo journalctl -u openfollow -f | grep -i osc
  2. Address format. Confirm /marker/<id> with three floats, or /marker/<id>/x (or /y, /z) with one float. Anything else is silently ignored.
  3. Port. Default is 8765 – verify your sender is hitting it.

Performance

High CPU or frame drops

  • Rule out throttling first. Heat or an under-powered supply throttles the Pi 5 and reads as frame drops and high CPU. Check System health in the diagnostics bundle for throttling, undervoltage, and thermal flags, or run vcgencmd get_throttled on the Pi – any result other than 0x0 means it throttled. Fix the cause: fit the official 27 W USB-C supply and add active cooling.
  • High CPU: disable Person Detection Experimental if you’re not using it.
  • Frame drops: camera bitrate is too high (especially H.265). Drop the camera to H.264 main profile, 4–8 Mbps CBR.
  • Pipeline restarts every few minutes: the camera is dropping its connection. Check Wi-Fi signal, PoE budget, or the camera’s health page.

Getting help

Filing a useful bug report

The fast path: attach a diagnostics bundle. Open the Overview tab and click Download diagnostics bundle in the Diagnostics section. The bundle already contains OpenFollow version, host info, runtime versions, redacted config, log tail, network interfaces, USB devices, and more. See Diagnostics.

If for some reason you can’t get a bundle, include manually:

  • OpenFollow version (commit hash if running from git).
  • Host: Pi model and Pi OS release.
  • Video source type and a redacted URL or device name.
  • Output protocols enabled, and which destination was failing.
  • The relevant excerpt of journalctl -u openfollow around the failure.

Either way, if the bug is reproducible, also include the exact steps from a clean state.

Report bugs at github.com/openfollowapp/openfollow/issues. Every report should include a diagnostics bundle.

For questions or feedback, join the OpenFollow Discord.

1. NDI® is a registered trademark of Vizrt NDI AB.

2. OpenFollow does not contain any NDI® code by itself. NDI® requires closed source NDI® Tools / NDI® SDK on the host system that need to be installed separately.