Super Farm
On this page

Troubleshooting

For operators whose farm, or one Android in it, does not do what it should.

Each row gives a symptom, what to check and the command that fixes it. The symptoms are the doctor's own check names and the error messages the code prints. Commands are written as sf ...; use .venv/bin/sf if sf is not on your PATH.

Start here#

Four commands answer most questions:

sf doctor            # 46 read-only checks of the machine, each with its fix
sf ls                # every Android and its state
sf info 3            # one Android in detail, including its last error
sf tasks             # background tasks and their per-device results

Where the logs are:

WhatCommand or file
The daemonsf service logs -f, or <home>/logs/daemon.log (sf serve also prints it)
One Android's containerssf logs 3
Android's own logsf logs 3 --logcat
One Android's network sidecardocker logs sf-net-3
Tunnel state and kill switchsf vpn status
Who changed what<home>/logs/audit.log
The NVIDIA relay<home>/logs/venus-relay-*.log

<home> is the farm home: sf config path prints the location of config.yaml inside it.

sf config set saves to config.yaml, and a running daemon reads the file at its next start. After a fix that uses it, restart the daemon:

sf service stop && sf service start      # or stop and rerun `sf serve`

Settings under android, resources, gpu, network and device reach an Android at its next restart (sf restart <selector>).

Install#

SymptomCheckFix
error: run this as your normal desktop user, not as root or with sudoYou started install.sh with sudo../install.sh
error: Super Farm needs an x86_64 machineuname -mNone. The Android images are x86_64 only.
error: paths with spaces are not supported for --venv / --homeThe checkout or the farm home has a space in its path../install.sh --venv ~/sf-venv --home ~/.local/share/superfarm
warning: host setup reported problemsRead the steps printed above the warning.sf host apply
You want to see what host setup would dosf host apply --dry-run
sf: command not foundThe virtual environment is not on your PATH.ln -s "$PWD/.venv/bin/sf" ~/.local/bin/sf
Doctor: Android binder fails with "exists for this kernel but is not loaded"lsmod | grep bindersudo modprobe binder_linux devices=binder,hwbinder,vndbinder
sf host apply
Doctor: Android binder fails with "this kernel has no binder support"Your kernel was built without binder.Debian and Ubuntu releases that split it out: sudo apt-get install -y linux-modules-extra-$(uname -r)
Arch: sudo pacman -S linux-zen linux-zen-headers, then reboot into it
Otherwise boot a kernel built with CONFIG_ANDROID_BINDER_IPC and CONFIG_ANDROID_BINDERFS
Doctor: Android binder warns "binderfs is not registered"sudo mkdir -p /dev/binderfs && sudo mount -t binder binder /dev/binderfs
Doctor: Container networking or Netfilter fails with "installed but not loaded"Module auto-loading is off on this host.sf host apply
Doctor: Kernel module auto-loading warnscat /proc/sys/kernel/modprobe prints nothing.sf host apply
Doctor: IP forwarding failssudo sysctl -w net.ipv4.ip_forward=1
sf host apply
Doctor: Docker installed failsThe doctor prints the install command for your distribution.
Doctor: Docker daemon failssystemctl status dockersudo systemctl enable --now docker.service
Doctor: Docker usable by this user failsid -nG does not list docker.sudo usermod -aG docker "$USER", then log out and in
Doctor: Docker storage driver fails with vfsdocker info --format '{{.Driver}}'Set {"storage-driver": "overlay2"} in /etc/docker/daemon.json, then sudo systemctl restart docker
Doctor: inotify limits or ARP / neighbour table size warnssf host apply
Doctor: Farm home filesystem fails with "no Unix permissions"The farm home is on NTFS, exFAT or FAT.export SUPERFARM_HOME=~/.local/share/superfarm
Doctor: Host setup applied warnsHost setup has not run, or only partly.sf host apply
Doctor: scrcpy warns that the live H.264 view is not supportedscrcpy --version. Windows and listening need no particular version; the H.264 view needs 2.1 up to 3.x.Download the upstream build from https://github.com/Genymobile/scrcpy/releases and put its folder first on your PATH.
After a reboot, Androids no longer startThe boot unit did not run.systemctl status superfarm-host.service
sf host apply --boot

sf host apply, the boot unit and sf service install have not been run for real during testing; see VERIFICATION.md. If one of them fails, sf host apply --dry-run prints every command so that you can run the failing one by hand.

An Android will not boot#

SymptomCheckFix
Android N stopped while booting. Last output: ...sf doctor
sf logs N
Fix what the doctor reports. To rule out the GPU: sf gpu set N software, then sf start N
Android N did not finish booting within 180 s. It is left runningsf top (is the machine overloaded?)
docker logs sf-android-N
sf config set performance.boot_timeout 300
sf config set performance.start_concurrency 2
Android N was started but cannot be reached: the adb program is not installedadb versionInstall your distribution's ADB package; sf doctor prints the command.
Android N: network (vpn) is not ready: ...docker logs sf-net-N
sf vpn status N
See VPN and kill switch.
a container named sf-android-N exists that this farm did not create; it is left alonedocker ps -a --filter name=sf-Remove or rename that container yourself, or use another prefix: sf config set docker.name_prefix farm2
Docker did not answer (...)docker infosudo systemctl enable --now docker.service
could not pull <image>: ...The host's internet connection; the image name in sf image ls.sf image pull 13
Android N: its data was written by Android X and it is now set to Android Ysf info NSet the version back: sf set N android_version=X. To go ahead and risk the data: sf set N android_version=Y --force
Android N uses the adopted volume ..., which no longer existsdocker volume lsRestore the volume, or give the Android a fresh one: sf set N data_volume=default
Android N is busy (...) or HTTP 409 busysf tasks --activeWait for the task, or cancel it: sf tasks t12 --cancel
An Android boots, then apps crash at start after a rendering changeThe start result's warnings in sf tasks <id>.sf recreate N. If one app still crashes: sf app clear N <package>

Only Android 13 has been booted in testing. An Android of another version that does not boot may be hitting something nobody has seen yet; sf logs N --logcat is the place to look.

No GPU, or a black screen#

SymptomCheckFix
You do not know what an Android draws withsf gpu ls
sf info N
Doctor: GPUs warns "no DRM render node found"ls /dev/dri/Install the GPU's kernel driver. Without one, Androids draw on the CPU.
gpu mode '<mode>' is not available: ...sf gpu ls lists every choice on this machine and why one is unavailable.Pick an available one: sf gpu set N igpu
render node /dev/dri/renderD... does not exist on this machinesf host gpussf gpu set N auto --node ""
Doctor: NVIDIA runtime for Android (Venus) warns "not built"ls <home>/overlays/venus <home>/overlays/venus-relaynative/venus/build.sh all --fetch-ndk (not verified end to end, see GPU.md)
NVIDIA Vulkan driver manifest ... not foundfind /usr/share /etc -name nvidia_icd.jsonsf config set gpu.nvidia.icd <that path>
Doctor: NVIDIA driver failscat /proc/driver/nvidia/versionInstall NVIDIA's own driver; the doctor prints the command for your distribution.
no access to /dev/dri/renderD129 for this userls -l /dev/dri/sudo usermod -aG render,video "$USER", then log out and in
cannot create /run/superfarm/venus/...ls -ld /run/superfarmsf host apply
relay for <node> exited with code ...The log named in the message, under <home>/logs/Fix what the log says, then sf start N
gpu mode 'nvidia' is ... on an Android that is not version 13sf info NThe NVIDIA runtime is built for Android 13 only: sf gpu set N igpu or sf gpu set N software
Every NVIDIA Android lost its picture at onceIs the relay still running? pgrep -x virgl_test_servsf restart <selector of the NVIDIA Androids>
NVIDIA Androids lose their picture when you log outThe relay runs in your user session.loginctl enable-linger "$USER"
The screen is black but the Android is bootedsf screenshot N -o shot.png
sf logs N --logcat
sf gpu set N software, then sf restart N, to see whether the GPU mode is the cause
CPU use is highsf gpu ls shows software in use. Software rendering costs about five times the CPU of a GPU mode.sf gpu set all igpu, then sf restart all

Never restart the relay while NVIDIA Androids run. Each of them holds connections to it and loses its graphics until it is restarted.

VPN and kill switch#

sf vpn status shows the tunnel state of each Android. The states below are the ones the farm reports.

SymptomCheckFix
State auth_failedThe VPN server rejected the username or password.sf vpn credentials default, then sf restart N
VPN profile ... asks for a username and password, and none is storedsf vpn credentials lists the stored names.sf vpn credentials default
State tls_errorThe certificate or key in the profile is wrong or expired, or something on the path blocks the handshake. Doctor: Clock synchronised.Download the profile again and import it: sf vpn import <file>
State dns_errorsf config get network.dns; the host's connection.sf config set network.dns 1.1.1.1,9.9.9.9
State unreachableNo server in the profile answered.Try another profile: sf set N network.vpn_profile=<name>, then sf restart N
State config_errordocker logs sf-net-N shows the option OpenVPN refused.Import a clean copy of the profile: sf vpn import <file>
State tun_error, or /dev/net/tun does not exist on this hostls -l /dev/net/tunsudo modprobe tun
sf host apply
pinned VPN profile ... does not existsf vpn profilessf vpn import <file>, or sf set N network.vpn_profile=default
A directive is missing from an imported profileThe first lines of the stored file name what was removed. Directives that can run programs are always dropped.None; this is by design.
network.vpn.extra_args: ... is not allowedThe option could run a program or read files in the sidecar.sf config unset network.vpn.extra_args
An Android behind a VPN has no connectivity for up to two minutesThe server went away. It is noticed after network.vpn.ping_restart_seconds (120). Traffic is dropped meanwhile; it does not leak.Wait, or sf restart N
Kill switch not shown as active on a vpn or gateway Androidsf vpn status N
docker exec sf-net-N /sf/killswitch.sh check
sf recreate N
Traffic leaves with the host's addresssf info N: is the mode proxy or direct? Is network.killswitch off?proxy mode has no kill switch. Use sf set N network.mode=vpn. To switch the kill switch back on: sf config unset network.killswitch
gateway '<name>' is not definedsf gateway lssf gateway add <name> --profile <profile>
gateway ... still serves N Android(s)sf gateway lsStop its Androids first, or sf gateway down <name> --force
docker.subnet_pool ... has no free /24 leftsf gateway lssf gateway rm <unused name>
A VPN sidecar cannot read its profile on a host with SELinuxDoctor: SELinux / AppArmorsudo chcon -R -t container_file_t <home>/vpn <home>/secrets
An Android cannot reach a device on your LANBy default private addresses are blocked.sf config set network.allow_lan true, then sf recreate N

WireGuard tunnels have not been connected in testing. If one does not come up, docker logs sf-net-N is the only evidence there is.

ADB#

SymptomCheckFix
You do not know an Android's ADB addresssf info NAndroid N is on 127.0.0.1:(5555 + N) by default: adb connect 127.0.0.1:5558 for Android 3
A start fails because the ADB port is takenss -ltnp 'sport = :5558'sf config set network.adb_port_base 15555, then sf recreate all
Doctor: Ports warns that ADB ports are inside the kernel's outgoing port rangecat /proc/sys/net/ipv4/ip_local_port_rangesf config set network.adb_port_base 5555
Doctor: ADB exposure or Published ADB ports warnssf config get network.adb_bindsf config set network.adb_bind 127.0.0.1, then sf recreate all
You need ADB from another machineADB has no authentication. Do not publish it.On the other machine: ssh -L 5558:127.0.0.1:5558 <farm host>, then adb connect 127.0.0.1:5558
sf shell refuses a commandThe denylist refuses wipes, power-off and firewall or route changes.If you mean it: sf shell N --force -- <command>

Panel and login#

SymptomCheckFix
sf: the daemon is not runningsf service statussf serve, or sf service start
The browser cannot connectsf open prints the address.sf serve
The daemon exits at start because the port is in usess -ltnp 'sport = :7700'sf serve --port 7701, or sf config set server.port 7701
the token is not valid (401)You pasted an old token.sf token prints the current one.
too many failed attempts; try again shortly (429)Several wrong tokens came from your address.Wait a minute and use the token from sf token.
You are signed out after a daemon restartSessions are kept in memory.Log in again.
this host name is not one the daemon answers to (403)You opened the panel under a name the daemon does not know.Use http://127.0.0.1:7700, or sf config set server.allowed_origins https://farm.example.com
missing or wrong X-SF-CSRF header (403)A script is using the browser's cookie.Send Authorization: Bearer <token> from scripts.
refusing to listen on <address> with server.auth_required offsf config unset server.auth_required
You want the panel on another machineDoctor: Panel exposuressh -L 7700:127.0.0.1:7700 <farm host>, then open http://127.0.0.1:7700
The token may have leakedsf token --rotate
sf service install fails or the service does not startsystemctl --user status superfarmsf serve in a terminal works without systemd.

The panel has been tested in Chrome only.

Live view#

SymptomCheckFix
A thumbnail shows "offline"sf ls: is the Android running? ADB cannot reach it.sf start N
A thumbnail shows "booting" for a long timesf logs Nsf restart N
The live view is slow (a few frames per second)It is using the screenshot stream.Install scrcpy for the H.264 view, or raise the rate: sf config set stream.live_fps 12
The H.264 view is not offered: "scrcpy-server was not found"scrcpy --versionInstall scrcpy, or export SCRCPY_SERVER_PATH=<path to scrcpy-server> before starting the daemon
The H.264 view is not offered: "scrcpy X is untested with this release"Tested: 3.3.x. Supported: 2.1 up to 3.x.sf config set stream.h264 on
A live view answers 503stream.max_viewers (64) are open.Close other views, or sf config set stream.max_viewers 128
Typing text with accents or other scripts failsThat path needs scrcpy on the host.Install scrcpy.
Native windows do not openDoctor: Desktop session (windows and sound)From a terminal in your desktop session: sf service install
systemctl --user import-environment DISPLAY WAYLAND_DISPLAY XAUTHORITY
systemctl --user restart superfarm

Automation#

SymptomCheckFix
A device shows "needs attention"sf auto runs t12 shows the device and the reason.Fix the screen by hand in the panel, then sf auto resolve t12 4 resume. Or sf auto resolve t12 4 skip, or abort.
could not read the screen: ...The screen never stops moving (video, animation)..venv/bin/python -m pip install -e ".[u2]"
sf config set automation.hierarchy_reader u2
A trained program stops at its first tapThe app was not on its first screen.sf app stop <selector> <package>, then run it again
A step does not find its elementsf auto run <kind> <name> N --dry-run finds every element and taps nothing.Record the task again and retrain: sf auto train <dataset>
Training left steps outThe warnings in the training task say which and why.Record more runs of the same task; three or more give a consensus.
A flow is refused when savedsf auto flows validate <file> prints the error with its position.
A flow refuses to type a textFlows type printable ASCII only.Type other text from the panel's live view, which pastes through the clipboard.
A value named like a password is refusedSecret-looking names are never stored.Pass it for one run: sf auto run flow <name> N --secret password
A pop-up is not dismissedA pop-up rule fires only when its guard and its dismiss control are both on screen.Teach the rule again from the live screen in the panel.
The list of runs is empty after a daemon restartRun status is kept in memory.None. Programs, flows, recordings and schedules are on disk.

Camera and audio#

sf camera status lists every reason the camera is not ready. The virtual camera picture has not been verified end to end; the microphone path has.

SymptomCheckFix
media.camera.enabled is offsf config get media.camera.enabledsf config set media.camera.enabled true
sf host apply
the v4l2loopback kernel module is not loadedlsmod | grep v4l2loopbacknative/v4l2loopback/build.sh build
sudo native/v4l2loopback/build.sh install
sf host apply
Doctor: Virtual camera module fails with "unsigned, and Secure Boot is on"sf host sign-module reports the Secure Boot state and the key.sf host sign-module -- v4l2loopback
sf host apply
N of 32 camera devices do not existls /dev/video*sf host apply
/dev/videoN is not a Super Farm camera ... refusing to write to itAnother program owns that device number.sf config set media.camera.device_base 150
sf host apply
no permission for N camera devicesid -nGsf host apply, then log out and in
the camera HAL overlay for Android 13 is missingls <home>/overlays/camera/13native/camera/extract_hal.sh --image <your Android 13 image> <BlissOS ISO> (see native/camera/README.md)
ffmpeg is not installedffmpeg -versionInstall the ffmpeg package.
The camera works until the container is recreatedThe installed HAL lives in the container.Bake the overlay into the image: copy it to <home>/overlays/android/13/vendor/, then sf image build 13
A test tone is silent in a voice appApps remove steady tones as noise.python3 scripts/camera/make_test_clip.py test.mp4 makes a clip with beeps; add it to the media library and play it.
The picture is mirroredsf config get media.camera.mirrorsf config set media.camera.mirror false
sf listen N: scrcpy is not installedscrcpy --versionInstall scrcpy.
sf listen N: Android N is not reachable over ADBsf lssf start N
sf listen N runs but nothing is heardDoctor: Desktop session (windows and sound). The daemon needs your session's sound server.systemctl --user restart superfarm from a terminal in your desktop session
The RTMP ingest is refused on another addressIt has no authentication.Keep 127.0.0.1 and tunnel: ssh -L 1935:127.0.0.1:1935 <farm host>

AI and MCP#

MCP.md and AI.md have their own tables. The most common cases:

SymptomCheckFix
the MCP SDK is not installedFrom the checkout: .venv/bin/python -m pip install -e ".[mcp]"
MCP access is switched offsf config get ai.mcp.enabledsf config set ai.mcp.enabled true
An assistant's action never runssf approvals ls --state pendingsf approvals watch, and answer Yes or No
A request expired before you answeredsf config get ai.approval_timeout_secondssf config set ai.approval_timeout_seconds 900
A tool is missing from the client's listsf mcp tools shows what the policy does with each tool.sf config set ai.policy ask, or remove the tool from ai.deny
The MCP client cannot start the serversf mcp config prints the entry with the paths of this install.Paste that entry into the client's configuration unchanged.
A model profile does not answersf ai models test <profile> reports each check.Fix what it reports; a missing key: sf ai models key <profile>
A Pilot run stops with "no progress"sf ai pilot show <session> --stepsRun it again with more runs: --runs 5

Performance and capacity#

SymptomCheckFix
not starting Android N: over capacity (...)sf host capacityStop some Androids, or sf start N --force. To be warned only: sf config set performance.enforce_capacity false
A start warns "over capacity ... Started anyway"sf host capacityNone needed. The estimate is advisory.
N MB of RAM is available; below performance.memory_guard_mbfree -msf stop <selector>, or lower the guard: sf config set performance.memory_guard_mb 1000
Androids are killed when memory runs outDoctor: Swap / zram warns "no swap at all".sf config set performance.zram.enabled true
sf host apply
The machine is slow with many Androidssf topsf gpu set all igpu; sf config set android.fps 15; then sf restart all
A bulk start overloads the machineBooting is the heaviest moment.sf config set performance.start_concurrency 2
Containers lose connectivity at random with many Androidsdmesg | grep -i 'neighbour table overflow'sf host apply
Doctor: Docker address space at scale warnsdocker network lsAdd larger pools to /etc/docker/daemon.json, as the doctor prints, then sudo systemctl restart docker
Doctor: Disk space warnsdocker system dfsf backup prune

The capacity figures were measured on one machine. SCALING.md explains how to read them on another.

Backups#

SymptomCheckFix
Android N has no data yet (volume ... does not exist); start it once firstsf start N, sf stop N, then sf backup create N
Android N is running; stop it first when restoring over itsf stop N, then sf backup restore <name> --over N
bad backup name ...sf backup list shows the names.sf backup restore android-3/20250101-040000
... does not match its recorded checksums; it is damaged or incompletesf backup verify <name> --deepRestore an older backup of that Android.
A restored Android has no networkA copy restored next to its original is created with network mode none, so one identity is never online twice.After deleting or stopping the original: sf set <new id> network.mode=default, then sf restart <new id>. Or restore with --keep-network.
A delete is refused because the safety backup failedsf backup list; free disk space.Fix the cause, or delete without the backup: sf rm N --force
A farm backup from another machine restored only part of its contentThe output lists what was not taken and why.Only for a backup you made yourself: sf backup restore farm/<time> --trust, with --restore-config or --restore-secrets as needed
Backups fill the disksf backup listsf backup prune keeps the newest backup.keep (7) of each Android.
tar failed (exit ...)docker info; free disk space under the backup folder.Free space, then run the backup again.

Still stuck#

  1. Run sf doctor --json > doctor.json and read every line that is not ok.
  2. Collect sf info N --json, sf logs N -n 200 and the last lines of <home>/logs/daemon.log.
  3. Check VERIFICATION.md: what you are doing may be on the "not verified" list.
  4. Open an issue with those files. Remove tokens, VPN credentials and addresses first.

Next#

This page is docs/TROUBLESHOOTING.md in the repository.