Troubleshooting
Every refusal Trinium prints at startup names its cause. Find the message here for the fix.
Runs are refused, but the app works. Your license key is missing, expired, or does not cover something the pipeline uses. The message names the reason. Settings → License shows the status, the expiry date and how many days are left; Trinium also shows a banner on every page for the last seven days before expiry. There is no grace period: the expiry date is the day runs stop. Everything else keeps working by design: nothing is deleted and nobody is locked out. Send us the message and we will sort the key out.
A container restarts in a loop and the log says Failed to connect to database. The connection string in secrets/db.key is wrong, or that database is unreachable from this server. Only the trinium profile brings its own database (see Choose what runs). If the file is missing entirely you get a different, clearer message naming it, rather than a connection failure.
docker compose up says a variable is not set. A required value in .env is blank. The message names it. Check that .env is the one the install page wrote, and that you are running from that directory.
The admin password keeps reverting after a restart. ADMIN_DEFAULT_PASS in .env still has a value, and it is re-applied on every start by design. Blank the line and restart (see Configure). (The first-start admin password is seeded once, on a brand-new database only, and never re-applied.)
Nobody can sign in. A fresh install signs in as admin / admin. If that password has been changed and forgotten, put a new one in ADMIN_DEFAULT_PASS in .env and run docker compose up -d; it is reset on every start while that value is present. Blank it again once you are back in.
Trinium will not start and the log says this database already holds encrypted data. There is no secrets/master.key, but this database was encrypted with one. Trinium will not generate a replacement, because a different key cannot read the credentials and backups the original wrote, so minting one would destroy them silently. Put the original key back at secrets/master.key and start again.
If the key is genuinely gone, recover from a portable backup instead:
- Start Trinium against an empty database. It generates a new master key for itself.
- Sign in, go to Settings → Backup → Restore, and upload the portable bundle.
- Everything returns except saved credentials. Open each connection and enter its password again; do the same for the SMTP relay, any sign-in provider, and the backup destination.
This only works for a portable backup. A default backup is encrypted with the master key that wrote it and cannot be read without it, by anyone, including us.
A worker will not start and the log says there is no master key here, or that the database has no Trinium tables yet. A worker never creates either; the web server (trinium, core or controller) does on its first start. With controller,worker on one server this can happen once on a fresh install; the worker restarts by itself and starts as soon as the controller has. On a worker server of its own, copy secrets/master.key from your web server (see Scaling out).
A worker will not start and the log says the database is newer or older than the worker, or a different build. Every server must run the same Trinium version. Upgrade the web server first, then each worker (see Upgrading).
Trinium will not start and the log says the key is not the one this database was encrypted with. The file in secrets/ is a different key from the one in use. Two common causes: copying a key from another Trinium instance, or restoring one server's backup onto another without bringing its key. Put the matching key in place.
Trinium will not start and the log mentions MASTER_KEY. You are upgrading from a version that took the master key from the environment. Move the value into the file and remove the variable:
printf '%s\n' 'your-existing-master-key' | sudo tee secrets/master.key > /dev/null sudo chown 10001:10001 secrets/master.key && sudo chmod 600 secrets/master.key
tee, because sudo in front of printf does not help: your shell performs the redirect before sudo runs.
Then delete the MASTER_KEY line from .env (see Upgrading).
Trinium will not start and the log says a folder "must belong to uid 10001". Trinium runs as uid 10001 and nothing in it runs as root, so it cannot take over a folder or a file someone else owns. The usual causes: the install page's step 2 was skipped, so Docker created secrets/ or backups/ itself, owned by root; or a key, db.key or certificate was written into the folder as yourself. The log line ends with the command that fixes it, for example sudo chown -R 10001:10001 secrets && sudo chmod 700 secrets, run from the folder holding compose.yaml. Then run docker compose up -d.
Trinium will not start and the log names cert.pem or key.pem. You have one half of a certificate pair in tls/ and not the other. Trinium refuses to start rather than quietly serving plain HTTP to someone who believes they set up HTTPS. Add the missing file, or remove the one that is there to go back to plain HTTP (see Turning on HTTPS).
Trinium will not start and the log says the certificate could not be loaded. Both files are present but they are not a usable pair. The usual causes: the key is passphrase-protected (it must not be), the two files do not match each other, or a copy truncated one of them. Check them with openssl x509 -in tls/cert.pem -noout -subject and openssl pkey -in tls/key.pem -noout -check.
I put a certificate in tls/ and it is still serving HTTP. The files must be named exactly cert.pem and key.pem, and they must be files: if you bind-mounted a path that did not exist, Docker created an empty directory of that name. ls -l tls/ will show it. The startup banner always names the transport, so check docker compose logs | grep "Server running".
The sign-in page says "Too many failed sign-in attempts." Five wrong passwords for one username within 15 minutes lock that username for 15 minutes, the built-in admin included. It unlocks on its own; a restart does not unlock it sooner. Other usernames are unaffected, and every refused attempt is in the audit trail.
Single sign-on will not finish setting up. Identity providers refuse a non-HTTPS redirect URI. Turn on HTTPS, or put Trinium behind a proxy that terminates TLS, and set Trinium URL in Settings → Authentication to the https:// address people actually use.
Trinium says it could not find a connection string. secrets/db.key has to exist beside compose.yaml before the first start on every profile except trinium (see Configure). The message names both the path inside the container and the path on your server; the one you can reach from your shell is the second. Upgrading a core install? The connection string used to be DATABASE_URL in .env and that setting is gone (see Upgrading).
docker compose pull says access denied or repository not found. The registry sign-in (Sign in to the registry) has not been done on this server, or the token was pasted with a trailing space. Re-run it; docker login prints Login Succeeded when it works.
Uploads fail with a permission error after an upgrade. An install that predates the current file layout can have a file volume owned by the wrong user. Fix it once, with Trinium stopped:
docker compose down docker run --rm -v trinium_filedata:/d alpine chown -R 10001:10001 /d docker compose up -d
Pipelines are slower than expected, or the log mentions spilling to disk. Trinium is trading memory for disk rather than failing. Open Settings → General → Engine memory: it shows the whole sum, including what the database is holding back. Give the server more RAM, or move the database off this host with the core profile. On Docker Desktop, see Running on Docker Desktop: the memory to raise is the virtual machine's.
docker stats shows the database sitting near its 2 GB limit. Expected, and not a leak. That figure includes the file cache Linux keeps on the database's behalf, which is charged to the container and given straight back under pressure.
Anything else. Include the output of docker compose ps, the last hundred lines of docker compose logs, and the version shown in the app's Help footer. That footer identifies your exact build and is the first thing we ask for.