Common error messages
A lookup from the text you see in a log or the browser to what it means and where to fix it.
- Get the text with
docker compose logs <service>(see how to read the logs). - Find it in the table for that area below.
- Follow the fix link.
Startup and configuration
| You see | Cause | Fix |
|---|---|---|
Invalid environment: followed by a field name | A required .env value is missing or malformed, so the api exits rather than run half-configured | Set the named value. See install and startup. |
JWT_SECRET: String must contain at least 16 character(s) | The session-signing secret is blank or too short | Set a strong 16+ character value: openssl rand -hex 32, or regenerate with the builder. |
TENANT_CREDS_ENCRYPTION_KEY: String must contain at least 16 character(s) | The credential-encryption key is blank or too short | Set a strong value, but read the key warning before changing it on an instance that already stored credentials. |
Malformed encrypted credential payload | A stored credential is being read with a different TENANT_CREDS_ENCRYPTION_KEY than it was written with | Restore the original key, or reconnect the integration and re-enter its secret. See Secrets and keys. |
The api container restarts and a log line names a .sql file | A database migration failed on boot | Read the SQL error under it, then check disk space and that images are current. See migration failed on boot. |
address already in use on docker compose up | Another process holds the web port (8088 by default) | Free the port or set WEB_PORT in .env. See port already in use. |
Images and registry
| You see | Cause | Fix |
|---|---|---|
denied or unauthorized on docker compose pull | Usually a wrong image reference or COBBLR_VERSION tag, not a permission problem: the images are public | Check the image lines and COBBLR_VERSION against what the setup builder generated. See image pull is denied. |
HTTPS and the proxy
| You see | Cause | Fix |
|---|---|---|
unknown COBBLR_TLS_MODE '...' in caddy logs | The TLS mode is misspelled | Use cloudflare, internal, tsnet, or the legacy duckdns. |
To authenticate, visit: https://login.tailscale.com/... in caddy logs | Not an error. The Tailscale (tsnet) node is waiting for you to approve it, which is the default when no TS_AUTHKEY is set | Open the link and approve the node. Find it again with docker compose logs caddy | grep -iE 'to authenticate|login.tailscale'. See tsnet never comes up. |
SSL_ERROR_INTERNAL_ERROR_ALERT in the browser, on Tailscale (tsnet) | No certificate was issued, because COBBLR_SITE_ADDRESS is not a name this node owns. The node still shows Connected | Compare the machine's full name in the admin console to COBBLR_SITE_ADDRESS, and check whether a leftover node took the first part. See SSL_ERROR_INTERNAL_ERROR_ALERT. |
A Caddyfile parse error on a bare email line | An older image with a blank COBBLR_ACME_EMAIL | Pull the current image (it self-heals) or set COBBLR_ACME_EMAIL. See caddy crash-loops. |
A certificate error for Cloudflare (or legacy DuckDNS) in caddy logs | Wrong DNS token, or the box has no outbound internet | Fix the token or connectivity. Certificates cache after the first issue. See the certificate didn't issue. |
Access
| You see | Cause | Fix |
|---|---|---|
| The camera never opens on your phone | The camera requires HTTPS or localhost, and a plain LAN address isn't secure | Turn on HTTPS, or scan on the box at localhost. See the phone camera is blocked. |
| A public name resolves but the page won't load | DNS rebind protection is refusing a public name that points at a private IP | Add an exception or a local DNS entry. See a name resolves but won't load. |
| Signup is closed and nobody can sign in | Closed signup with no operator account | Recoverable with one .env edit, since you own the box. See Operating. |
- "I forgot my password" is not an error but lands here anyway. The login page's reset link needs the instance to have email delivery. Without it, the operator mints a temporary password from the admin console. Both paths are in A forgotten password.
If your symptom isn't here, the health check and
docker compose logs narrow it to a container fast.