Repository navigation
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 |
|---|---|---|
| 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 |
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-streamRuns entirely on your LAN · Full configuration reference in README.md · Pi preparation and backup in deploy/README.md
- Home
- Get started — build & run
- Configuration
- Solcast
- Weather
- Troubleshooting
Advanced
- Docker
- Platforms
- Deployment — Pi, two workflows
- MQTT
Images: ghcr.io/mpospisil/solax-controller