Troubleshooting
Grouped by where the problem is, because the first useful question is always which half is broken.
The site will not start
Section titled “The site will not start”Read the log first — docker compose logs app — because the server says exactly why.
| What the log says | What it means |
|---|---|
SECRET_ENC_KEY must be set in production |
The key that encrypts stored secrets is missing. Set it in .env and start again. The container crash-loops until you do. |
A BOT_INTERNAL_KEY complaint |
Blank, still a placeholder, or shorter than 16 characters. Required in production even when the bot is not running. |
| A database connection error, repeatedly | The app came up before the database was ready, or DB_* is wrong. The Compose file’s health check handles the first case; check the values for the second. |
| Nothing at all, container restarting | The image did not pull. docker compose pull on its own shows the error. |
Nobody can sign in
Section titled “Nobody can sign in”- Your address is rate-limited or bot-banned. Both are working as designed. Check Admin → Web Bot Activity from another network, or restart the app container — the scoring state is in memory and resets with it.
- The password is right and the form still fails. Check the log for the actual status:
a
429is the rate limiter, a403is usually the honeypot, and a401really is the password. - SSO returns to the login page. SSO is link-only: an identity that is not already linked to an account cannot sign in, and that is the expected outcome rather than a misconfiguration. Link it from the account screen first.
- Two-factor is lost. Recovery codes, or another admin’s Reset two-factor on Users → View. See Authentication.
A module will not start
Section titled “A module will not start”Admin → Modules names the stage and the reason. The usual three:
| Reason | Fix |
|---|---|
module directory not present on the volume |
The row exists and the files do not — someone deleted the directory by hand. Reinstall, or remove the row with an uninstall. |
| A schema failure | The module’s schema fragment could not be applied. The log carries the SQL error. |
| A version refusal | The module wants a newer core API than this image. Upgrade the site. |
Whatever the reason, the site is up and the module’s routes are absent — that is by design, and it is why a broken module is an inconvenience rather than an outage. Fix the cause and restart: failed modules are retried on every boot.
The install button rejects a URL. The host must be in the allowlist on the same screen, and the URL must be HTTPS. An empty allowlist forbids every install.
The install succeeds and nothing appears. It needs a restart. The banner says so, and the row reads Restart to start until then.
The Restart button did not bring the site back
Section titled “The Restart button did not bring the site back”The button exits the process and relies on a supervisor to start it again. If your
deployment has nothing supervising it — npm start in a terminal, a container without
restart: — the site stays down until you start it yourself. Compose with
restart: unless-stopped is the supported shape.
The game screens are empty or say offline
Section titled “The game screens are empty or say offline”Work outwards from the game, and stop at the first check that fails.
- In game:
[bridge status—connected=Falsemeans the shard cannot reach the sidecar. - On the shard host:
curl -s http://127.0.0.1:8080/health—plugin_connected: trueis the value that matters. - On the shard host:
runicgateway doctor— checks the install record, every overlay file hash, the service, and that the sidecar and overlay agree on a protocol. - On the site: the shard connection screen — its four indicators say which link is broken.
Two log lines with specific meanings: 409 is a protocol mismatch (set the Protocol
field to what /health reports), and 401 is the auth token (read the live one back
with uo-link-sidecar --print-config; do not retype it from a screenshot).
Teams are missing
Section titled “Teams are missing”Check the sync panel on Admin → Teams before anything else: last success: never with
no uo-link configured means the shard connection, not the Team machinery. And on a site
with no module installed, an empty Team list is correct and final — core cannot create
a Team. See Teams.
Email and announcements never arrive
Section titled “Email and announcements never arrive”- The contact form opens a mail client. Email delivery is not configured; that is the documented fallback. Enter SMTP credentials in Settings → Email delivery. If this site used to send mail and stopped, the Gmail connect flow was removed — the admin dashboard says so, and Notifications and email has the migration.
- Mail is configured but nothing arrives, and there is no error. Two usual causes, both invisible without a test send. Implicit TLS left on for port 587 hangs rather than failing; and a Send from address the server will not let you send as is rejected for SPF/DMARC reasons. Press Send test — its failure message names both cases.
- Email was working and the toggle is still on. Enable email sending now gates every message, not just some of them. If it is off, nothing is sent, including the contact form.
- A published post announced nothing. The Discord bot is a separate container. If the Discord Bot screen says bot unreachable, it is not running.
- A missed announcement does not come back. Nothing retries; the post itself is still on the site.
Nothing is sent for one particular event
Section titled “Nothing is sent for one particular event”Mail works, other notifications arrive, but this one thing never produces anything. The answer is almost always in Engagement → Rules, and it is one of four:
- The rule is off. Every rule ships disabled, including the ones your modules bring with them, so “installed” is not “on”.
- The rule is badged dormant. It is switched on but cannot fire — usually because the module that declared its trigger, or the audience it points at, is no longer installed.
- It fired and was held back by its own cooldown, which is per person, per subject and per channel. The Send Log shows nothing for a message that was never queued.
- The audience resolves to nobody. The rule editor’s reach preview is the fastest way to find that out — it will tell you the count is zero and why.
Engagement rules walks through all four.
One person stopped receiving email
Section titled “One person stopped receiving email”Everyone else is getting mail, so the transport is fine. Check Engagement → Suppressions, then Engagement → Send Log.
- They are on the suppression list. The site stops mailing an address once the
receiving server says the mailbox does not exist. Addresses are stored one way and
shown masked (
d***@example.com), so search by their domain to find the row. If they have since fixed their mailbox, press Lift a suppression and type the full address — the screen genuinely does not have it, which is why you are asked. - Suppression only affects engagement rules. Password resets, invites and address verification still go out to a suppressed address, because those are things the person asked for themselves. So “they can reset their password but get no notifications” is the expected shape of this problem, not a contradiction.
- The Send Log says Not sent. That is a suppression: nothing was sent to the mail server at all. Bounced means it was sent and the mailbox does not exist. Failed means the relay refused it for some other reason — that one is about your configuration, not about them.
- The Send Log has no row for them at all. They were excluded before anything was queued. Either they have not opted in on Notifications for that stream, or Require a verified email address is on in Settings and they have not confirmed theirs. The rule editor’s audience preview shows how many people each of those removes.
Everyone stopped receiving email at once
Section titled “Everyone stopped receiving email at once”Do not start clearing the suppression list — it is almost certainly not the cause. A whole-deployment stop is a transport problem: an expired password, a relay that has started refusing you, or Enable email sending switched off. The Send Log will show Failed rather than Bounced or Not sent, and Settings → Email delivery shows the last error. A wrong password never suppresses anybody; only the receiving server saying a specific mailbox does not exist does that.
Uploads and modules fail with permission errors
Section titled “Uploads and modules fail with permission errors”Docker created a bind-mount source that the container user cannot write — usually because
the directory was deleted and recreated by Docker as root. chown 1000:1000 modules (or
logs, or brand) on the host fixes it. Do not delete those directories.
When you need to ask for help
Section titled “When you need to ask for help”Bring three things: the relevant lines from docker compose logs app, the output of
runicgateway doctor if a game server is involved, and what you changed last. The
community page has where to ask.