Troubleshooting
First aid
Section titled “First aid”Server: view the container logs. After the installer, the commands run in /opt/bitwerk with sudo
(for a checkout, in the repository folder):
cd /opt/bitwerksudo docker compose logs -f control-server media-serviceRaspberry Pi: service logs (with the web kiosk -u hifi-display instead of -u hifi-kiosk).
journalctl -u hifi-player -u hifi-kiosk -fHealth check: sudo docker compose ps shows healthy or unhealthy; details of the last check are given by sudo docker inspect --format "{{json .State.Health}}" <container>. From outside (prints status, version and number of tracks):
curl http://<server>:8080/api/healthServer and web UI
Section titled “Server and web UI”| Problem | Cause | Solution |
|---|---|---|
Installer stops with Port … is used by … | another program (a web server, a Postgres on the host, a second bitwerk) holds a port bitwerk needs | stop or move that program; the line names it and its PID. Postgres on the host: sudo systemctl disable --now postgresql |
Installer stops at Docker Desktop detected or on macOS | Docker Desktop has no host networking towards the LAN, players would not find the server | install on Linux with Docker Engine; for a trial only, answer yes to continue |
Installer says No prebuilt image for: … and builds | the registry has no image for this version or architecture, or is unreachable; the lines after it say which | use a released version (--version), check the network; the build needs 2 GB RAM |
| control-server does not start, log mentions the password | neither ADMIN_PASSWORD_HASH nor ADMIN_PASSWORD set | enter ADMIN_PASSWORD_HASH in .env (a plain ADMIN_PASSWORD is for testing), see Quick start |
media-service does not start, log mentions MEDIA_URL_SECRET | a secret set in .env is shorter than 32 characters or differs between the services | usually leave it empty: the control-server generates it on first start; if you set it, use openssl rand -hex 32 and the same value for both services |
| Login works, then immediately logged out again | reverse proxy does not pass Host through, or SESSION_COOKIE_SECURE=true without HTTPS | check the proxy configuration |
| “Too many attempts” (429) | login lockout after 5 failed attempts | wait 5 minutes (LOGIN_LOCKOUT_SECS) |
| Cover art missing in the web UI | media-service unreachable or secret differs between the two services | set MEDIA_URL_SECRET identically |
control-server unhealthy | database unreachable (store_ok: false) or service hangs | sudo docker compose logs control-server postgres; the healthcheck checks /api/health including the database |
control-server stays in created/waiting | Postgres not healthy (the control-server waits only for Postgres) | sudo docker compose logs postgres (disk full, port 5432 taken, permissions on the data volume) |
| Settings → Backups says backups are not set up or the last backup failed | no backup timer on the host (--no-backup-timer, a checkout, no systemd), or backup.sh failed | systemctl list-timers bitwerk-backup.timer, journalctl -u bitwerk-backup -u bitwerk-backup-now; sudo deploy/install.sh --backup-timer sets the units up |
Uploads and library
Section titled “Uploads and library”| Problem | Cause | Solution |
|---|---|---|
File stays in uploads/ | upload is still running or the file keeps changing | wait for 2.5 s of quiet; check the log |
Permission denied when you copy into uploads/ | your user is not in the group hifi yet, or the login predates it | log out and in again (id lists hifi); the installer adds the user who ran sudo |
Log reports Permission denied or cannot create directories, Settings → Library shows a permission warning | container runs as UID 10001, the music folder or copied files belong to another user without group write access | run the command shown in the warning, see Operations |
File ends up in uploads/_unsorted/ | title or artist tag missing, format unknown or file damaged | reason under Settings → Uploads; add tags, upload the file again |
| Uploads are not noticed (Docker on NAS/Windows) | file system events do not arrive through the bind mount | wait for the periodic rescan (RESCAN_INTERVAL_SECS, 10 min) or click Rescan in Settings → Library |
Adding a USB drive fails: cannot read /media/<user>/<label>: Permission denied | a desktop (udisks2) mounted the drive for one user only; the media-service runs as UID 10001 | run sudo /opt/bitwerk/deploy/drives.sh once on the server, then pull the drive and plug it in again: it is mounted read-only at /media/<label> and offered in Settings → Library (External drives) |
| Deleted albums do not disappear | no rescan since then | click Rescan in Settings → Library, or wait for the periodic rescan |
Player
Section titled “Player”| Problem | Cause | Solution |
|---|---|---|
| Player does not appear under Clients | discovery broadcast does not arrive (different VLAN, firewall, Docker Desktop) | same network, open UDP 53535, or set HIFI_SERVER + HIFI_PLAYER_ID |
Log not paired | player has no token: Extended security is on, the player was blocked, it reaches the server through a reverse proxy or from a public address, or more than 10 new players joined within 10 minutes | pair it, or approve a blocked one in Settings → Clients |
pairing failed: invalid or expired pairing code | code expired (10 min), already used, server restarted | generate a new code |
| Display shows “DSP” instead of “Bit-Perfect” | volume below 100%, ReplayGain, monitor function, PEQ or resampling active, or the room follows a room group | intended? otherwise reset the setting or use HIFI_VOLUME=hardware/fixed; in a group only the leading room stays bit-perfect |
Grouped rooms are audibly apart, player log server clock does not answer | UDP 53536 blocked by the server’s firewall, or an old player | open UDP 53536 on the server; update the player |
| Grouped rooms are a few ms apart although in sync | speakers with their own delay (DSP, distance) | set Room delay per room under Rooms → Advanced |
hw:… output is not available in this build | built without --features alsa | use the .deb from the release or build with --features alsa |
Device or resource busy | PipeWire/PulseAudio holds the DAC | disable the audio server, see Raspberry Pi |
Dropouts, log jitter buffer underrun | Wi-Fi or network overloaded | Ethernet, HIFI_BUFFER_MS=4000 |
| Status light in Settings → Clients is yellow or red | the reasons next to it: under-voltage now or in the last 10 min, a warm or hot SoC, firmware throttling, dropouts | a stronger power supply (for a Pi 4 the official 5.1 V / 3 A one), airflow or a heatsink, Ethernet; Settings → Logs shows when it started |
| Status light stays grey | the player is offline, or it is too old to send readings | check its network and service (journalctl -u hifi-player); update the player |
| Identify does not blink the LED | log cannot blink the activity LED for identify: the udev rule or the service’s write permission is missing | update or reinstall the player package and reboot, see Raspberry Pi |
No audio, dropouts and crackles
Section titled “No audio, dropouts and crackles”Work from the source to the DAC: the web UI shows what the player reports, so start there.
| Symptom | Check | Solution |
|---|---|---|
| Track “plays” in the web UI, nothing comes out | DAC label next to the player name in the player selector: missing means the engine has no open output | journalctl -u hifi-player -n 50; check ALSA_DEVICE with aplay -l, see Raspberry Pi |
| Player shows offline although the Pi runs | log control connection failed or version mismatch | network path to port 8080, or see Version mismatch |
| Silence after a track change or seek | log playback-info failed | media-service reachable on 8082 from the Pi? MEDIA_URL_SECRET identical on both services? |
Short dropouts, log jitter buffer underrun | Wi-Fi, a busy switch or the Pi throttling (vcgencmd get_throttled not 0x0) | Ethernet, a better power supply, HIFI_BUFFER_MS=4000 |
| Constant crackles or clicks | sample rate or format the DAC does not lock to, often with DSD over DoP | set HIFI_RATES/HIFI_DSD to what the DAC really supports, see the DAC list |
| Crackles only at high volume | digital clipping from ReplayGain plus PEQ boost | lower the PEQ preamp, check the “DSP” reasons in Now playing |
| Sound, but not “Bit-Perfect” | volume, ReplayGain, PEQ or resampling active | see the Player table above |
Version mismatch
Section titled “Version mismatch”Server and players check each other’s version when a player connects. A player that is too old for the server, or a server that is too old for the player, is refused instead of playing with half-understood commands.
- Web UI: Settings → Clients shows each player’s version; a red Player too old or Server too old names the side to update (the tooltip has the full text). The player selector marks the player with ⚠.
- Touch display: a yellow line “Update needed: …” above the title.
- Player log (
journalctl -u hifi-player):version mismatch: player 0.1.0 (protocol 1) and server 0.2.0 (protocol 2) are incompatible: …, logged once; the player retries every 30 s, so it reconnects by itself after the update. - Server log:
player refused: …with the player ID.
Update the side the message names: players with sudo apt update && sudo apt upgrade, the server with
sudo /opt/bitwerk/deploy/update.sh (see Operations). The simplest rule is to keep server
and players on the same release. A player shown as unknown is older than the check itself; it keeps working, but
update it as well.
curl http://<server>:8080/api/health prints the server version, hifi-client --version the player version.
Touch display
Section titled “Touch display”| Problem | Solution |
|---|---|
| The splash stays, or a black screen | systemctl status hifi-kiosk, journalctl -u hifi-kiosk (web kiosk: journalctl -u hifi-display -u hifi-player-kiosk) |
| Picture upside down or turned | KIOSK_ROTATE=0, 90, 180 or 270 in player.env, then sudo systemctl restart hifi-kiosk |
| Touch does not respond | journalctl -u hifi-kiosk; the unit brings the group input itself (web kiosk: user hifi in input, done by sudo hifi-setup --display --kiosk web) |
| Screen goes dark | dimmed after KIOSK_DIM_AFTER seconds without a touch while nothing plays; a touch wakes it, 0 keeps it on |
More DAC-specific hints are in Set up a Raspberry Pi.
Reporting a problem
Section titled “Reporting a problem”If nothing here helps, open an issue with the Bug report form on GitHub. It asks for:
- what happened and what you expected, with the steps to get there,
- the versions of server and player (see Version mismatch),
- how the server is installed and which Pi, DAC and display the player uses,
- the log lines around the problem: Settings → Logs in the web UI or
docker compose logs --since 10m control-server media-service, andjournalctl -u hifi-player -u hifi-kiosk --since "10 min ago"on the Pi (web kiosk:-u hifi-display), - the diagnostic bundle: Download diagnostics under Settings → Logs in the new web UI. It is one JSON file with the server’s configuration, every player’s status light and readings, and the device events; passwords and tokens are left out.
Remove passwords, tokens and pairing codes before you paste logs. DAC problems have their own forms (DAC request, DAC report), ideas go into Feature request.