Troubleshooting
Organised by what you see, not by what is broken.
First moves
Local only
# odoocli server infoLocal only
# docker psLocal only
# docker logs odoo-api --tail 200For anything that was started from the console or by a schedule, the Jobs page is a better starting point than any log: every operation captures its own.
Installation
| Symptom | Cause and fix |
|---|---|
No Odoo server configuration exists on server install | odoo.json is still the scaffold. Run odoocli server config create --preset production first |
server update or server upgrade refuses to run | You ran it inside a container. It recreates the API's own container, so it must run on the host |
| Installation succeeds but no mail is sent | No SMTP profile was configured, so the Postfix container was not installed. This is a warning, not a failure |
The console and the API
| Symptom | Cause and fix |
|---|---|
| Every API call returns 401 | The console's key does not match any of the API's. Re-run server install, or server apikey rotate, then update remote clients |
| Every API call returns 503 | odoo.json failed to load. Check the API's health endpoint and the odoo-api log |
| The console says the API is unreachable | odoo-api is not running or not listening on 5210 |
| A configuration change had no effect | odoo.json is read once at API startup. Restart odoo-api |
| Passkey registration fails, password sign-in works | You reached the console by IP address. Use the host name: a relying-party id must be a domain |
| Nobody can sign in | Reset from the host with odoocli user password-reset, user totp-disable or user unlock |
Instances
| Symptom | Cause and fix |
|---|---|
| Certificate request fails | DNS does not point here, or port 80 is not reachable. Check with instance config validate-dns |
| A fresh 15.0 or 16.0 instance will not initialise a database | Those versions reject an empty addons path. Antelao omits the path entirely until a module exists; if you added one by hand, remove it |
| An instance runs but cannot write | Try instance repair filesystem |
| A rebuilt image is still broken after pulling again | docker pull reuses the existing local layer. Remove the image and prune the builder cache, then pull |
Odoo container image for version X was not found | The container and image ids disagree, or the instance still refers to an image tagged under an older product name. Re-tag rather than rebuild |
| An applied configuration change did nothing | Some settings need the container recreated, not restarted. Bind mounts, addons paths in particular |
Jobs
| Symptom | Cause and fix |
|---|---|
| A job is stuck at Queued | Another job holds the instance, or a server-level job is draining the queue. Both are by design |
A job is Interrupted | The API restarted while it ran. It is not retried automatically because half-done work can be destructive. Read its log and decide |
| A job failed naming an edition | A licensing denial. It names the capability, not the code. See Editions |
| A generated password is not shown any more | It is revealed once, briefly, and then gone. Reset it |
Backups
| Symptom | Cause and fix |
|---|---|
| Backups run but nothing reaches S3 or Azure | Either the credentials are wrong, or the licence lapsed. A lapse skips cloud targets and records a failed result per target, while local and FTP copies still run. Check the job result per target |
| Scheduled backups stopped silently | The scheduler needs Professional. An expired subscription stops unattended runs while manual ones keep working |
| A schedule did not fire after an outage | The scheduler does not catch up. Run it by hand for the missed window |
| An instance is not covered by the server-wide sweep | It holds its own schedule of that type, which excludes it from the sweep. Remove the per-instance schedule to return it |
Licensing
| Symptom | Cause and fix |
|---|---|
| A licence worked for two weeks and then stopped | It was never activated. An unactivated licence runs on a non-renewable 14-day window from first sight. Activate it against this server's challenge |
| A licence installs and is refused immediately | It is bound to a different machine. The activation window is only for a licence never activated anywhere |
| A previously working licence stopped | The hardware changed, the check-in grace window ended, the clock was rolled back, or the licence does not cover this product version. The Licence page names which |
| The server unregisters after a hardware or hypervisor change | The challenge changed. Reactivate |
| The Licence page reports the state file is unwritable | The licence directory is read-only. The grace window still ends, but the anchor is only in memory |
Fail2Ban
| Symptom | Cause and fix |
|---|---|
| Bans are listed but attacks continue | Almost certainly a reverse proxy in front of nginx. See the trusted-proxy warning in Fail2Ban; check the f2b-<jail> chain counters, not the ban list |
| A ban has no instance | Jails are server-wide. The instance is derived from the database named in the match, and not every jail carries one |
| You banned yourself | odoocli server fail2ban unban works at every edition, including unregistered, precisely for this |
Upgrades
| Symptom | Cause and fix |
|---|---|
| An older binary refuses to start after a rollback | The master schema upgrade is forward-only. Restore the master database from before the upgrade |
Diagnostics worth keeping to hand
Local only
# docker logs odoo-web --tail 200Local only
ls -t /root/.local/share/odoocli/logs/ | headLocal only
# odoocli server info --show-secrets