Troubleshooting
Server fails to start
Section titled “Server fails to start”Port 7777 already in use
Section titled “Port 7777 already in use”BarkVisor’s HTTP server binds to port 7777 by default (configured in Config.port). If another process is using that port, the server will fail to start. Check for conflicts:
lsof -i :7777Kill the conflicting process. The server always binds to 0.0.0.0.
Permission errors on data directory
Section titled “Permission errors on data directory”For installed daemon builds, BarkVisor stores all data under:
/var/lib/barkvisor/For development builds (swift run):
| Platform | Default data directory |
|---|---|
| macOS | ~/Library/Application Support/BarkVisor/ |
| Linux | ~/.local/share/barkvisor/ |
Override with BARKVISOR_DATA_DIR. If the directory or its contents have incorrect permissions, the server will fail during initialization:
ls -la /var/lib/barkvisor/# or: ls -la ~/.local/share/barkvisor/Database corruption recovery
Section titled “Database corruption recovery”On startup, BarkVisor attempts to open and migrate the SQLite database at:
/var/lib/barkvisor/db.sqlite # installed daemon~/Library/Application Support/BarkVisor/db.sqlite # macOS dev~/.local/share/barkvisor/db.sqlite # Linux devIf the database fails to open, the server automatically attempts to restore from the most recent backup in the backups directory. If no backup is available, a fresh database is created (all data is lost). Check server logs for messages like Database failed to open or Database restored from backup.
Database backups are enabled by default and run daily. The backup directory defaults to:
/var/lib/barkvisor/backups/ # installed daemon~/Library/Application Support/BarkVisor/backups/ # macOS dev~/.local/share/barkvisor/backups/ # Linux devBackup retention is 30 days by default, configurable via the backupRetentionDays UserDefaults key.
Checking server logs
Section titled “Checking server logs”BarkVisor writes structured JSON logs to:
/var/lib/barkvisor/logs/ # installed daemon~/Library/Application Support/BarkVisor/logs/ # macOS dev~/.local/share/barkvisor/logs/ # Linux devOverride with BARKVISOR_LOG_DIR. Levels: debug, info, warn, error, fatal. On macOS, BarkVisor also logs to the unified log (subsystem dev.barkvisor).
# macOSlog stream --predicate 'subsystem == "dev.barkvisor"' --level debug
# Linux (systemd install)journalctl -u barkvisor.service -fLinux-specific
Section titled “Linux-specific”Install checklist and packages: getting-started-linux.md.
- QEMU not found: install distro QEMU (see the Linux install checklist). On Rocky/Alma/RHEL the binary is often
/usr/libexec/qemu-kvm— BarkVisor resolves that path. - UEFI guest fails to boot: ensure OVMF/AAVMF packages are installed; HAOS needs a real VARS template (not an empty file).
- Bridge fails: configure
/etc/qemu/bridge.conf(allow br0) and setuid onqemu-bridge-helper. Under systemd, do not setNoNewPrivileges=trueon the unit (packaged unit allows the setuid helper). - Blank SPA after package install: confirm
/usr/local/share/barkvisor/frontend/disthasindex.html(orBARKVISOR_FRONTEND_DIR). - Slow guests: many nested/cloud hosts lack
/dev/kvm→ TCG. Add thebarkvisoruser to groupkvmwhen KVM is present, then restart the service. - Stop / restart (systemd):
sudo systemctl restart barkvisor.serviceandjournalctl -u barkvisor.service -f.
Onboarding issues
Section titled “Onboarding issues”Re-triggering setup
Section titled “Re-triggering setup”BarkVisor shows a web-based setup screen on first launch when no admin user exists. Setup completion is tracked in the database (the presence of a user with a non-empty password).
To re-trigger setup, delete the database and restart BarkVisor:
# macOSsudo launchctl bootout system/dev.barkvisorsudo rm /var/lib/barkvisor/db.sqlitesudo launchctl bootstrap system /Library/LaunchDaemons/dev.barkvisor.plist
# Linuxsudo systemctl stop barkvisor.servicesudo rm /var/lib/barkvisor/db.sqlitesudo systemctl start barkvisor.serviceThen open http://localhost:7777 to go through the setup wizard again.
Password validation
Section titled “Password validation”During onboarding, the initial password must be at least 10 characters. The password is hashed with bcrypt before storage. If a password has already been set for the default user, onboarding will report an error.
Catalog sync failures
Section titled “Catalog sync failures”On first launch, BarkVisor seeds a default image repository and templates from remote JSON files hosted on GitHub. If these fetches fail (network issues, DNS resolution, corporate proxy), the image library will be empty. You can trigger a manual sync from the web UI’s image library page, or check that the URLs are reachable:
https://raw.githubusercontent.com/pmdroid/barkvisor/refs/heads/main/repos/images.jsonhttps://raw.githubusercontent.com/pmdroid/barkvisor/refs/heads/main/repos/templates.jsonQEMU and VM issues
Section titled “QEMU and VM issues”QEMU binary not found
Section titled “QEMU binary not found”macOS release installs look for qemu-system-aarch64 and qemu-img in /usr/local/libexec/barkvisor/. During development (swift run), fallback order is:
/opt/homebrew/bin//usr/local/bin/- PATH lookup via
which
brew install qemuLinux uses distro QEMU on $PATH (Rocky/RHEL often ship /usr/libexec/qemu-kvm). Install QEMU from the distro using the Linux install checklist.
Firmware not found
Section titled “Firmware not found”BarkVisor resolves QEMU firmware (EFI images, VGA BIOS) from:
/usr/local/share/barkvisor/qemu/(macOS installed daemon)/opt/homebrew/share/qemu///usr/local/share/qemu/(macOS Homebrew)- Distro OVMF / AAVMF paths on Linux (edk2 packages)
If VMs fail to boot with firmware errors, verify the firmware files exist at one of these paths.
VM log files
Section titled “VM log files”Per-VM stdout/stderr output is captured in:
/var/lib/barkvisor/logs/vms/ # installed (macOS/Linux)~/Library/Application Support/BarkVisor/logs/vms/ # macOS dev~/.local/share/barkvisor/logs/vms/ # Linux devCheck these logs for QEMU error messages, boot failures, or crash output.
VMs survive daemon restart (by design)
Section titled “VMs survive daemon restart (by design)”When the BarkVisor daemon stops, running QEMU processes are intentionally left alive. The daemon detaches its monitoring but does not kill the processes. On next launch, VMProcessMonitor scans the PID files directory:
/var/lib/barkvisor/pids/ # installed (macOS/Linux)~/Library/Application Support/BarkVisor/pids/ # macOS dev~/.local/share/barkvisor/pids/ # Linux devEach .pid file contains the QEMU process ID. If the process is still running, BarkVisor reconnects to its QMP and VNC sockets and resumes monitoring. If the process has exited, the stale PID file is cleaned up and the VM state is updated in the database.
This means a quit-and-relaunch cycle does not interrupt running VMs.
Forcing VM cleanup
Section titled “Forcing VM cleanup”If a VM appears stuck in a running state but its QEMU process is gone, delete the corresponding PID file and restart BarkVisor:
sudo rm /var/lib/barkvisor/pids/<vm-id>.pidsudo launchctl kickstart system/dev.barkvisorHelper and networking
Section titled “Helper and networking”macOS: privileged helper and socket_vmnet
Section titled “macOS: privileged helper and socket_vmnet”On macOS, bridged networking uses a privileged XPC helper (BarkVisorHelper) plus socket_vmnet. The helper is a LaunchDaemon at /Library/LaunchDaemons/dev.barkvisor.helper.plist (binary /Library/PrivilegedHelperTools/dev.barkvisor.helper, Mach service dev.barkvisor.helper).
If the helper is not running, managed bridge operations will fail:
sudo launchctl print system/dev.barkvisor.helpersocket_vmnet is bundled at /usr/local/libexec/barkvisor/socket_vmnet in release installs, or under Homebrew opt prefixes in development:
brew install socket_vmnetEach bridge has a unix socket from the socket_vmnet daemon. If a VM cannot connect:
- Verify the LaunchDaemon plist exists and the daemon is running
- Check that the socket file is present at the expected path
Bridge state is synced periodically by BridgeSyncService. XPC errors (XPC connection interrupted / invalidated) usually mean a team ID mismatch, missing plist, or helper not approved in System Settings. Timeouts: 5 s general, 15 s for bridge install/remove/start/stop.
Linux: host bridge
Section titled “Linux: host bridge”On Linux, bridged VMs use QEMU -netdev bridge with a host br* interface and qemu-bridge-helper ACL in /etc/qemu/bridge.conf. See Bridged networking.
Frontend
Section titled “Frontend”Blank page in the web UI
Section titled “Blank page in the web UI”If you see a blank page at http://localhost:7777, the frontend has not been built. During development, build it with:
cd frontend && bun install && bun run buildThe server searches for the frontend dist/ directory in several locations:
BARKVISOR_FRONTEND_DIRif set and containsindex.html/usr/local/share/barkvisor/frontend/dist/(installed daemon)Sources/BarkVisor/Resources/frontend/dist/(dev probes)frontend/dist/(dev probes)
On Linux, ./scripts/linux-frontend-serve.sh builds the SPA and can start the daemon with the correct env. If none of these paths contain index.html, the SPA middleware is not registered and non-API routes return 404.
API proxy errors
Section titled “API proxy errors”The frontend expects the API to be served from the same origin. CORS is configured to allow requests from http://localhost:7777 and http://127.0.0.1:7777 when the server binds to 0.0.0.0. If you access the UI from a different hostname, CORS will reject the requests.
WebSocket ticket failures
Section titled “WebSocket ticket failures”WebSocket and SSE connections use a single-use ticket system instead of passing JWTs in URL query parameters. The client exchanges its JWT for a short-lived ticket via an authenticated POST endpoint, then passes only the ticket in the connection URL.
If WebSocket connections fail with authentication errors:
- Ensure your JWT has not expired
- Check that the ticket was consumed successfully (tickets are single-use and time-limited)
- Verify the server clock is accurate (ticket expiry depends on system time)
Code signing
Section titled “Code signing”Hypervisor entitlement
Section titled “Hypervisor entitlement”QEMU requires the com.apple.security.hypervisor entitlement to use Apple’s Hypervisor.framework. Without it, VMs will fail to start with a permission error. This entitlement is applied during the build process (see scripts/build-release.sh step 10).
For ad-hoc signed development builds, ensure the entitlement is present:
codesign -d --entitlements - /path/to/qemu-system-aarch64Gatekeeper blocks the installer
Section titled “Gatekeeper blocks the installer”If macOS blocks the BarkVisor .pkg installer, go to System Settings > Privacy & Security and click “Open Anyway”. For properly notarized builds (created with --require-notarize), Gatekeeper should not intervene.
XPC team ID mismatch
Section titled “XPC team ID mismatch”In release builds, the build script injects the real APPLE_TEAM_ID into the helper protocol source before compiling. If the team ID in the main app does not match the team ID in the helper, XPC connections will be rejected by macOS. This typically happens when:
- The build was not done with
build-release.sh(the team ID stays asDEVELOPMENT) - The helper and main app were signed with different identities
- The helper was replaced without rebuilding the main app
Performance
Section titled “Performance”Metrics polling frequency
Section titled “Metrics polling frequency”The metrics collector polls each running VM via QMP every 5 seconds and stores samples in a ring buffer of 360 entries (30 minutes of history). If you have many VMs, this can generate significant QMP traffic. Metrics are not persisted to disk.
Disk info cache
Section titled “Disk info cache”Disk size information is refreshed every 30 seconds by running qemu-img info on each disk. This runs in the background and results are cached in memory. If you have a large number of disks, the refresh cycle may take noticeable time.
Concurrent qemu-img operations
Section titled “Concurrent qemu-img operations”Disk creation, resizing, and info queries all invoke qemu-img as a subprocess. These are not globally rate-limited, so creating many disks simultaneously may cause resource contention.
Diagnostics
Section titled “Diagnostics”Diagnostic bundle
Section titled “Diagnostic bundle”BarkVisor provides an API endpoint to generate a diagnostic bundle. The bundle is a .tar.gz archive containing:
system-info.json— host OS version, CPU count, physical memorybarkvisor-info.json— app version, uptime, data directory pathsvm-states.json— currently running VMs with their PIDs and VNC socket paths- Recent log files
The bundle is created in the system temp directory and automatically cleaned up after 15 minutes.
Database backups
Section titled “Database backups”Automatic database backups run daily when enabled (on by default). Backups are stored in:
/var/lib/barkvisor/backups/ # installed (macOS/Linux)~/Library/Application Support/BarkVisor/backups/ # macOS dev~/.local/share/barkvisor/backups/ # Linux devYou can customize the backup directory and retention period (default 30 days) via the settings API or UserDefaults keys backupDirectory and backupRetentionDays.
Log levels
Section titled “Log levels”The application log system supports five levels in increasing severity: debug, info, warn, error, fatal. Logs are written as JSON lines with fields for timestamp, level, category, message, and optional VM ID, request ID, and error details. Old log files are pruned daily.
Rate limit bypass for testing
Section titled “Rate limit bypass for testing”Login rate limiting (10 attempts per 5-minute window per IP) can be disabled by setting the environment variable:
DISABLE_RATE_LIMIT=1This is intended for automated testing only.