Skip to content

Troubleshooting

martin edited this page Aug 16, 2026 · 5 revisions

Troubleshooting

Most of these fail quietly rather than loudly, which is what makes them worth listing — the container looks healthy while doing the wrong thing.

Symptom → cause → fix

Symptom Cause Fix
All telemetry zero or the log repeats connection errors Wrong device address, or Modbus TCP not enabled on the device nc -vz <host> 502 first — see Get started
dotnet build fails on the target framework An older SDK on PATH .NET 10 SDK required; check with dotnet --version
Numbers look implausible rather than absent Register map doesn't match your firmware Keep the charge mode Off and verify against the inverter's own display before enabling any write
Nothing on http://localhost:8090 The UI is on by default, so this is a fault, not a missing setting. Web__Enabled=false is the one setting that turns it off Look for Web UI enabled; listening on port 8090 in the log; check ss -ltnp; see Configuration
In a container: log says the UI is listening, browser can't connect The container's port isn't published -p 8090:8090, or in Compose an obsolete COMPOSE_FILE= line in .env overriding the base file — delete it and redeploy
Container exits at startup, "RequireAuthentication is true but PasswordHash is not set" Web__RequireAuthentication=true with no hash — nobody could ever sign in Intentional fail-fast — set a hash, or just delete the RequireAuthentication line (unset means "follow the password")
The UI asks for no password Expected — there is no login until Web__PasswordHash is set See Configuration if you want one
Container healthy, log files never appear Host directory not writable by uid 1654 — the log sink fails silently chown -R 1654:1654 on data and logs
Sessions recorded on the wrong day Windows container running in UTC — .NET ignores TZ Set Controller__TimeZone to a Windows zone id
mem_limit has no effect on a Pi cgroup memory accounting disabled in cmdline.txt See Platforms, then confirm via /proc/cmdline
Nothing connects to the broker Mosquitto refuses anonymous connections and has no password file Create passwd, owned by 1883
Worker exits immediately at startup A timezone id that cannot be resolved Intentional fail-fast — correct the id rather than unset it
Forecast sensors stay empty No Solcast credentials Optional feature — see Solcast
Version reads 0.0.0-dev A local build, not a CI-published image Pull from GHCR rather than building on the host
Entities missing in Home Assistant Discovery messages not arriving Tap the broker — see MQTT
Controller not running, and the log ends with stopped cleanly at the request of… Somebody pressed Stop service. Working as designed — it stays down docker compose start solax-controller; see Deployment
It comes straight back after pressing Stop service Restart policy is unless-stopped (or always), which restarts on any exit Use restart: on-failure, which reads the exit code — see Docker
Controller gone with no stopped cleanly line at the end of the log The process died rather than stopped — killed, OOM, or the power went The absence of that line is the diagnosis; check docker inspect --format '{{.State.ExitCode}} {{.State.OOMKilled}}' and mem_limit
Gave up pausing the charger on shutdown after 00:00:10 The charger stopped answering Modbus while the service was shutting down A car may still be drawing at the last setpoint — check the charger. The deadline is deliberate: waiting longer risks a SIGKILL mid-write
Shutdown takes 20 s or more A Modbus read already in flight can't see the stop until it times out; a silent device costs 5 s per exchange Expected. stop_grace_period is 60s to cover it

Reading the startup log

The first line names the running build, e.g. 1.0.0 (31bf347). That same string appears as the device's software version in Home Assistant, so a mismatch between the two tells you the container you are looking at is not the one Home Assistant is talking to.

A run that ends properly also names how it ended, on its last line — either stopped cleanly at the request of <surface> (exit code 0, stays down) or stopped cleanly after a termination signal (exit code 143, comes back). A log that ends without either one is a run that died, which on a Pi is often the only evidence there is: the journal is RAM-only, so it does not survive the reboot and these files do.

# how the last few runs began and ended, in order
grep -h -E "starting\.|stopped cleanly" logs/solax-*.log | tail

docker compose logs -f solax-controller
docker compose ps
docker stats --no-stream

Previous: Solcast · Back to Home

SolaX Local Controller

Advanced


Images: ghcr.io/mpospisil/solax-controller

Clone this wiki locally