Skip to content

When it will not start

Work down this page in order. The first three sections cover most of what actually goes wrong.

Check the log first. It almost always names the cause.

In the logCauseFix
EADDRINUSESomething already has port 3000, 4000 or 443Find it (netstat -ano on Windows, ss -ltnp on Linux). On Windows Server, IIS binds 443 by default
ENOENT on a .pem or .pfx pathThe certificate path does not exist, or the service account cannot read itCheck the path. Remember the service runs as a different account
ECONNREFUSED to 5432PostgreSQL is not running, or DATABASE_URL points at the wrong hostStart the database. On Docker, docker compose ps
password authentication failedWrong password in DATABASE_URLCompare against what the database actually has
A Prisma migration errorThe schema is from a different versionSee migrations below
Administrator rights are requiredNot elevatedUse sudo, or an elevated shell on Windows
  1. Is the process running? ./plugboard service-status, systemctl status plugboard, or docker compose ps.
  2. Is it listening? ss -ltnp | grep -E '3000|4000', or netstat -ano | findstr "3000 4000".
  3. Is a firewall in the way? Test from the machine itself first with curl http://localhost:3000. If that works and remote does not, it is network, not application.
  4. Is the reverse proxy pointing at the right place? A proxy configured for localhost will not reach a container. A proxy configured for a container name will not reach a host process.

PUBLIC_URL (or WEB_URL) does not match the address in the address bar. https://x, https://x/ and http://x are three different values. Fix it and restart.

The Host header does not match a tenant’s primaryDomain, and the first hostname label is not a tenant slug either. On a single-tenant install, set DEFAULT_TENANT_SLUG. On a custom domain, set the tenant’s primaryDomain. See your own domain.

Usually a clock problem. Tokens are time-bound, and a server whose clock has drifted rejects its own freshly issued tokens. Run NTP.

If JWT_SECRET was changed, everybody is logged out by design. Sign in again.

A proxy is buffering /api/events/*. Turn buffering off for that path. See HTTPS and certificates.

Migrations are forward-only and idempotent, so re-running is safe. The failures that happen are:

The database already has a newer schema than the application. You rolled the image back without restoring the database. Restore the dump taken before the update.

A migration failed halfway. The dump the update script took in step 2 is the way back. Restore it, then investigate before trying again.

Permissions. The database user needs to create tables. A user granted only SELECT and INSERT on existing tables cannot migrate.

Apply them by hand if you need to:

Terminal window
node scripts/plugboard.mjs migrate

Every connector reports a decryption error and nothing authenticates.

SECRETS_MASTER_KEY does not match the one in use when the backup was taken. The data is fine; the vault cannot be opened. Set the correct key and restart.

If the key is genuinely lost, the credentials are not recoverable. Reconfigure each connector from its source system. This is the failure the backups page exists to prevent.

SymptomCause
“HTTPS not started” in the logWrong certificate path, or wrong PFX password. The log names the file it tried
Browser warns about the certificateSelf-signed, or the intermediate chain is missing. Set TLS_CA_FILE
Works on a desktop, fails on AndroidMissing intermediate chain. Same fix
Cannot bind 443On Linux, reinstall the service so the capability is granted to the right account. On Windows, something else has the port
Let’s Encrypt never issuesPort 80 unreachable from the internet, so the HTTP-01 challenge fails. Use a tunnel or a DNS-01 challenge
SymptomCause
Updates never arriveAUTO_UPDATE is off, or the machine cannot reach the update endpoint. ./plugboard update --check says which
Update refuses with a checksum mismatchThe download was corrupted or tampered with. It is meant to refuse. Try again
Update reported success but the version did not changeA tag resolved to the old image. Pin a digest
The service did not come back after an updateCheck the log. The previous version is in .previous-version if you need to go back
  1. Is there an email connector configured and enabled? Nothing sends until there is one. See SMTP.
  2. Is it in demo mode? Demo mode does not send.
  3. Did the test connection pass? Run Save and test on the connector.
  4. Is the message switched off? Some templates can be disabled. See email messages.
  5. Is the link wrong rather than the send failing? Then it is PUBLIC_URL, not email.

Modules gate navigation. If a section is missing, its module is off, or your role lacks the permission, or your licence tier does not include it. Check in that order:

  1. Admin, Features. Is the module enabled?
  2. Admin, Roles. Does your role hold the permission?
  3. Admin, Licence. Does your plan include the module?
  • Endpoint protection scanning the data directory. The usual answer on Windows. Exclude .pgdata or the Docker volume.
  • Audit log size. Set a retention policy. See audit and retention.
  • A connector timing out. A screen that waits on a slow MDM feels like the application is slow. Check the connector’s test connection latency.
  • Disk. A nearly full volume makes PostgreSQL crawl before it fails.

If you need to raise something, this is what makes it answerable on the first reply:

Terminal window
curl -s https://helpdesk.yourschool.org/api/health/version

Plus: which install method, which operating system, the last hundred lines of the log around the failure, and what changed immediately before it started. That last one solves it more often than anything else on this page.