Troubleshooting
If something's wrong, this is where to start. Each section is a symptom-first table β find the row that matches what you're seeing and try the fixes in order. Most problems fall into a handful of buckets: wrong RTSP credentials, time-zone misconfiguration, or Docker not yet started.
Camera won't connect
| Symptom | Things to try |
|---|---|
| Camera shows "Disconnected" in the dashboard or main window |
Verify the RTSP URL is exactly right (including the port and stream path);
the camera is powered on; camera and PC are on the same network;
you're using the camera account credentials (not the TP-Link
cloud login). Test the URL in VLC
(Media β Open Network Stream) to isolate whether
the problem is the camera or the app. Try /stream2 if HD
won't load.
|
| Connection keeps dropping every few minutes | Improve Wi-Fi at the camera; reserve a static IP (Part 4); reduce simultaneous streams (cloud recording / SD recording / NVR); enable periodic reconnect; set Tapo cloud credentials so the app can auto-reboot the camera (desktop only). |
| "Authentication failed" or 401-like error | You're almost certainly using the wrong credentials. On Tapo, the Camera Account (set in the Tapo app under Advanced Settings) is a separate username/password from your TP-Link cloud login. |
| Camera works in VLC but not in BirdWatchAI | Confirm the URL is byte-for-byte identical. Some camera firmwares require a trailing slash; some refuse a connection from more than one client at a time β close VLC and try again. If you have ONVIF motion enabled, try turning it off β a few firmware combinations refuse the ONVIF subscription and refuse to stream RTSP until you reboot the camera. |
| H.264 corruption / green flicker / picture freezes mid-stream | Wi-Fi saturation. On Tapo, drop the main stream from 2K to 1080p in the Tapo app (avoid 2K β it saturates the camera's uplink). On other brands, drop the bitrate or switch to the sub-stream. Wired Ethernet to the camera eliminates this almost everywhere. |
| ONVIF motion not firing on a Tapo camera | Tapo ONVIF subscriptions have a 1-hour lease (renewed every ~45 min). Stale subscriptions after a camera reboot or network blip can cause BadRequest until the old lease expires (~1 h) or you reboot the camera. Toggling ONVIF off and on in settings forces a fresh subscription too. |
No / wrong detections
| Symptom | Things to try |
|---|---|
| No detections at all, but the camera shows live video | Make sure you clicked Start Monitoring; check that it's within daylight hours (or disable that limit in Settings β Monitoring); lower the Motion Threshold; confirm Test Mode is off. |
| Too many false detections (squirrels, wind, shadows) | Raise the Motion Threshold; increase the Cooldown; keep the object detector on; frame out swaying branches. Use the Telemetry viewer (desktop) to find a good threshold. |
| Wrong species, or low confidence on obvious birds | Get the camera closer to the feeder (3β10 feet); use the HD stream; keep best-frame extraction on; raise the confidence threshold; use Correct Identificationβ¦ to fix mistakes (the correction is saved and helps future training). |
| Squirrels / other animals are ignored | Expected β the object detector filters non-bird motion to keep your history clean. There's no setting to "save squirrels" by design. |
| "Bird" gets detected on shadows / sun flares | Move the camera so direct sun isn't in the frame; clean the lens; raise the confidence threshold. The object detector occasionally false-fires on high-contrast moving shapes. |
Notifications
| Symptom | Things to try |
|---|---|
| Email won't send (Gmail) | Gmail rejects regular passwords for SMTP. Enable 2-Step Verification, then create a 16-character App Password (Google Account β Security β App passwords β Mail) and use that. Keep SSL on. Click Send Test Email to verify. |
| Email won't send (other providers) | Check the SMTP server name and port. Many providers require a specific "from" address that matches the authenticated user. Some providers block SMTP for new accounts for 24 h. |
| ntfy phone app doesn't get notifications | Confirm the topic in the phone app is byte-for-byte identical to the one in BirdWatchAI settings (case-sensitive). Confirm the phone has internet + battery-optimization isn't killing ntfy in the background. Send a test from the settings page. |
| Pushover delivers but the photo is missing | Your image is probably above Pushover's 5 MB attachment limit. Either drop the snapshot resolution at the camera or accept text-only push. |
| Photo frame doesn't update (FTP) | Verify the host, port, username, password, and remote path; many frames require FTPS rather than plain FTP. The πΌ Test Photo Frame button surfaces the underlying error. |
Server / Docker
| Symptom | Things to try |
|---|---|
| Dashboard returns "site can't be reached" |
Run docker ps β is birdwatch listed with status
Up? If Restarting or missing,
docker logs birdwatch shows why.
|
docker compose up fails with "Cannot connect to the Docker
daemon" |
Docker isn't running. On Windows, open Docker Desktop from the Start menu
and wait for the whale icon to settle. On Linux, sudo systemctl
start docker.
|
denied: requires authentication on
docker compose up |
The GHCR package isn't public yet (early-access install). Open an issue on the release repo so the owner can flip the visibility. |
| "β¬ Update available" button is greyed out |
Your install predates the Watchtower sidecar. Update the manual way once
(cd ~/birdwatch && docker compose pull && docker
compose up -d), then re-pull the release repo so the new
docker-compose.yml wires the sidecar in.
|
| Container running but dashboard shows old version |
docker compose pull && docker compose up -d β the
pull is a no-op if the local image is already current, but recreates the
container if a newer image got pulled. Hard-refresh the browser
(Ctrl+Shift+R) after the recreate.
|
| Watchtower container in a restart loop |
Almost always a Docker API version mismatch. The supplied
docker-compose.yml pins DOCKER_API_VERSION=1.44
which works on current Docker daemons. If you changed it, restore the
pin.
|
| Out of disk on the host |
Snapshots and clips grow without bound by default. In Settings β Storage,
set a retention policy (e.g. delete snapshots older than 30 days). Then
docker system prune -af to reclaim old image layers.
|
Raspberry Pi specific issues
| Symptom | Things to try |
|---|---|
ssh: Could not resolve hostname birdwatch.local |
Use the Pi's IP instead of .local. Find it in your router's
admin page. |
Permission denied (publickey,password) |
Username typo, or you didn't enable password SSH in the Imager's Services tab. Re-image the SD card. |
docker: command not found after the install step |
The Docker install script failed silently. Re-run
curl -fsSL https://get.docker.com | sh and watch for
errors. |
| Pi camera: "No cameras available!" inside the container |
You probably missed step 4 (uncommenting privileged: true in
docker-compose.yml). Confirm with
docker inspect birdwatch --format '{{.HostConfig.Privileged}}'
β it should print true. See
Part 4 β Raspberry Pi
camera.
|
| Pi locks up randomly under load | Almost always an underpowered USB-C supply. Use the official Pi 4 / 5 power supply. |
| Wi-Fi works briefly then disappears (Pi 5) | Wi-Fi country code isn't set. Run
sudo raspi-config nonint do_wifi_country US (substitute your
country code). |
Windows-specific
| Symptom | Things to try |
|---|---|
| App seems gone but tray icon still showing | It minimized to the tray. Double-click the tray bird icon to restore. Use tray β Exit to fully quit. |
| "Pick on Map" shows no map | Install the Microsoft WebView2 Runtime. Manual latitude / longitude entry still works without it. |
| Installer says "WSL 2 installation incomplete" (server Docker) |
Open PowerShell as Admin β wsl --install β reboot β re-run
the Docker Desktop installer.
|
| App won't start: ".NET 8 Desktop Runtime missing" | Download and install the .NET 8 Desktop Runtime (x64) from microsoft.com, then re-launch BirdWatchAI. |
Detection timestamps off by several hours
This one bites every install at some point.
On a Raspberry Pi
Pi OS defaults to Etc/UTC if you skipped the time zone in the Imager
customisation step. Fix:
sudo timedatectl set-timezone America/New_York
# (substitute your zone β list them with `timedatectl list-timezones | grep America`)
cd ~/birdwatch && docker compose restart birdwatch
Verify with docker exec birdwatch date β it should now match your wall
clock.
On Windows with Docker Desktop
Docker Desktop on Windows runs containers in a Linux VM that uses its own
timezone. The compose file's TZ env var picks up ${TZ}
from your environment β set it explicitly: edit docker-compose.yml
and replace ${TZ:-UTC} with e.g. America/New_York,
then docker compose up -d.
On the desktop app
The desktop app uses your Windows system clock and time zone directly, so this problem is rare. If you see it, check that Windows shows the right time and the right zone (Settings β Time & Language β Date & time).
Collecting diagnostics for a support request
If you've tried the above and need help, gather:
Desktop
- In Settings β Debug Logging, raise component levels (or "Set All to High"). Reproduce the problem.
- Open the Debug Log panel or open the
Data\Logsfolder and grab the most recent file. - Include the app version (Help β About) and a brief description of what you did and what you expected.
Server
docker logs --tail 200 birdwatch
Plus the contents of data/config.json with passwords and
API keys redacted. Open an issue on the
release
repo with both.