GoRunner docs
Search or askSearch⌘K

Troubleshooting

Find what you see, then fix it.

Self-hosted

Start with the containers and their logs, in the install folder. A part that says Restarting or (unhealthy) is where to look; its log starts with the reason.

bash
docker compose ps
docker compose logs -f api worker

“another installation already runs as the compose project …”

Why

This server already runs a GoRunner under that name, from the folder the message names. Two would share their containers and data, so the setup changes nothing.

Fix

Give the second one its own name and ports:

bash
./setup.sh --project gorunner-2 --https-port 8443 --http-port 8080

“could not pull the images”, or “unauthorized”

Why

The server can’t reach the registry, isn’t signed in to it, or the version doesn’t exist. GoRunner’s images are private.

Fix
  1. Sign in again with your GitHub account’s user name and its read-only token: docker login ghcr.io -u <user name>. If the token ended, make a new one. See Sign in to the registry.
  2. Check the version’s spelling, with its v.
  3. For a mirror, sign in to it and give the setup its address: ./setup.sh --registry registry.example.com/ralve-org.

“1 problem. GoRunner was not started.”

Why

The preflight check found something GoRunner can’t work with. The ✗ lines above it say what, and what to change. On a re-run, .env is put back: “Nothing was started, and .env was not changed.”

Fix
  1. Fix what the line says, and run ./setup.sh again. The preflight check lists what it tests.
  2. Sure it doesn’t matter? Run the command after “Sure it’s fine?”: yours, with --skip-check.

“Going on would put data GoRunner already holds at risk” is never skipped: put the right encryption key back, or switch file storage on again.

“Could not get v2026.10.30’s bundle …”

Why

The version is misspelt, or the server isn’t signed in to the registry. Nothing was changed.

Fix
  1. Check the version, with its v.
  2. Sign in again: docker login ghcr.io -u <user name>. If your token ended, make a new one on GitHub.

“1 problem. Nothing was changed: … is still running.”

Why

The new version’s check found something to fix first. The old version keeps running.

Fix
  1. Fix what the lines above it say.
  2. Run the same ./deploy.sh again.

“building index … waited 1m0s for older transactions to end” means a long transaction, often a pg_dump, held up the migrations. Let it end, then run it again. Going back has its own rules.

The address doesn’t open, or has no certificate

Why

With automatic HTTPS, Caddy gets the certificate only once the domain points at the server and ports 80 and 443 reach it. Behind your own proxy, the proxy may not reach GoRunner.

Fix
  1. Check the domain’s A (and AAAA) record has the server’s public address, and the firewall opens 80 and 443.
  2. Read why: docker compose logs -f caddy. Caddy tries again by itself.
  3. Behind your own proxy, ask GoRunner directly on the server. {"status":"ok" means the problem is in the proxy.
bash
curl -sS http://127.0.0.1:8080/api/ready

The setup warns “… does not resolve yet” and goes on: Caddy keeps trying. It stops at “… does not answer over https yet”. Once DNS is right, run ./setup.sh again and answer y to “Check that everything is running with these answers?”.

Let’s Encrypt issues at most five certificates for one name a week. Never run docker compose down -v: it deletes Caddy’s.

A test install: “fetch failed” or CERTIFICATE_VERIFY_FAILED

Why

A test install on a laptop (--tls internal) uses Caddy’s own certificate. Browsers warn about it, and programs refuse it: your app’s server reports fetch failed (Node) or CERTIFICATE_VERIFY_FAILED (Python).

Fix

Save Caddy’s own authority in the install folder, and point your programs at it:

bash
docker compose exec -T caddy cat \
  /data/caddy/pki/authorities/local/root.crt > gorunner-test-ca.crt
curl --cacert gorunner-test-ca.crt https://gorunner.localhost:8443/api/ready
NODE_EXTRA_CA_CERTS=/path/to/gorunner-test-ca.crt node node.mjs
SSL_CERT_FILE=/path/to/gorunner-test-ca.crt python3 python.py

In the browser, accept the warning for this address before you try Embed, or the embed fails with nothing but a failed load in the console. For an Embed test, allow http://localhost:3000 under Allowed websites, and leave the key’s address list empty: the installation sees your app’s calls from Docker’s own network.

“That setup code isn’t right.”

Why

The code is 8 letters and digits, such as K7QM-4RZP, and only the server shows it. After 10 wrong tries from one network, the page asks you to wait 15 minutes.

Fix
  1. Print it again on the server:
docker compose exec api gorunner setup-code

“This installation already has an admin” means the account exists: sign in. With GORUNNER_ADMIN_EMAIL set, only that address can be the first admin.

The sign-in email doesn’t arrive

Why

It went to spam, the mail service refused it, or the installation is paused, when only platform admins get one.

Fix
  1. Look in the spam folder, and wait a minute before asking again: one address may ask once a minute and five times an hour, one network 20 times an hour. Only the newest email’s link and code work.
  2. Read what the mail service answered: docker compose logs api.
  3. Check the sender’s domain is verified with Resend, or has SPF and DKIM on your SMTP server.
  4. Run docker compose run --rm check: it signs in to the mail server without sending.

Port 465 expects TLS from the first byte; elsewhere set SMTP_SECURE=tls for that. Mixed up, it looks like a timeout. A mail server with a private certificate needs it in certs/. Some clouds block mail ports: use another port, or Resend. Change the answers with ./setup.sh.

“That email and password don’t match.”

Why

The password is wrong, there is no account with that address, or the person has no password yet. All three look the same on purpose.

Fix
  1. An owner or admin of their organization makes them a reset link. See Someone forgot their password.
  2. An admin who forgot their own runs gorunner reset-password on the server.

“Too many wrong passwords.” lifts after 15 minutes, or with a reset link. “Too many sign-in attempts from this network. Try again later.” counts wrong passwords from one network; the right password clears it. “This installation has no free seat” means every seat of the license is taken.

“Paused.”

Why

The license ended after its grace days, or no valid license is loaded. Nothing runs, and only platform admins can sign in.

Fix
  1. Next to Platform admin?, press Sign in.
  2. Load a license on the page that follows. See Start it again.

A license is refused

Why

The reason shows under the field.

Fix
It saysDo this
“That isn’t a license. Check that the whole text was pasted.”Copy the whole file again, first character to last.
“This license wasn’t issued for this product, or it was changed after it was issued.”Copy it again from the original. Still refused? Ask GoRunner.
“This license has already ended.”Ask GoRunner for a renewal. If it should be valid, check the server’s clock.
“This license names an edition this version doesn’t know.”Update to the version GoRunner gives you. A free license needs v2026.10.3 or newer.
“This build doesn’t accept free licenses. Use a GoRunner self-host image, v2026.10.3 or newer.”Install from GoRunner’s self-host image.
“The configured license was refused, so this installation runs without a license.”The LICENSE_KEY in .env isn’t valid. Load a valid license on the License card, which takes its place, or fix LICENSE_KEY.
“This installation has 2 organizations, 2 workspaces and 5 people …”It is bigger than the free license. Remove what is over, or keep a paid one. The free license

“The database CA file … is not a PEM certificate” and similar

Why

GoRunner couldn’t use the certificate authority file for your database. The line names the file.

Fix
It saysDo this
“… could not be read”, or “POSTGRES_CA_FILE … cannot be read”Put the file in certs/ and give its path inside the container, such as /certs/rds.pem.
“… is not a PEM certificate”Convert it: openssl x509 -inform der -in ca.der -out ca.pem.
“… holds a PEM certificate that could not be parsed”Download the CA again, as your database provider publishes it.
“… holds no certificate, only …”Give the CA’s certificate, a -----BEGIN CERTIFICATE----- block, not a key.

A container keeps restarting: REFUSING TO START

Why

GoRunner runs the quick part of the check at every start, and stops when something is missing or wrong. The sentence after REFUSING TO START: says what.

Fix
bash
docker compose logs api | grep "REFUSING TO START"
docker compose logs caddy postgres redis

Fix it in .env and apply it with ./deploy.sh "$(cat VERSION)".

“Platform needs a two-factor sign-in”

Why

The console opens only for a session signed in with two-factor. Either your account has none yet, or you turned it on during this session.

Fix
  1. Turn it on. See Turn on two-factor.
  2. Press Sign out and sign in again, and type the code.

No Platform in the menu means your account isn’t a platform admin. Every address showing the license page means the installation is paused.

The only platform admin lost two-factor

Why

Another platform admin would open the person in Platform › People and choose Reset two-factor…. There is no other admin.

Fix

Someone with the server runs:

docker compose exec api gorunner reset-two-factor dana@example.com

It works for a platform admin only. It turns their two-factor off, deletes their recovery codes, ends their sessions and records it in the audit log. When it works, it says “Two-factor is off for dana@example.com, and every session they had has ended.” They then turn two-factor on again.

No platform admin can sign in

Why

Nobody can open the Platform console.

Fix

The server’s operator has a console of their own at /admin, the Instance console. It is closed until you set a secret.

  1. Make a secret with openssl rand -hex 32 and set it as PLATFORM_ADMIN_SECRET: in .env, then ./deploy.sh "$(cat VERSION)"; on Kubernetes, in your Secret.
  2. Open https://automations.example.com/admin, type it as Console secret and press Unlock.

There you can Activate license or Revoke license…. The same secret, in an X-Platform-Admin header, makes an existing account a platform admin:

bash
curl -X POST https://automations.example.com/api/instance/platform-admins \
  -H "X-Platform-Admin: $SECRET" -H "Content-Type: application/json" \
  -d '{"email":"dana@example.com"}'

Remove the secret again afterwards.

On Kubernetes

You seeDo this
helm install stops with a sentence such as “encryptionKey is required…”A value is missing or wrong; the sentence names it.
The migrations Job failsRead its check: kubectl logs job/<its name> -c check.
Pods stay in ImagePullBackOffThe cluster can’t download the image: check it reaches ghcr.io, the ghcr Secret and imagePullSecrets.
Pods stay in Init:0/1They wait for the migrations. Read the Job’s log; kubectl get jobs lists it.
App pods run but aren’t readyGoRunner can’t reach the database or Redis: kubectl logs deploy/gorunner-api.
The address answers 404 or 502The Ingress has no address yet, or DNS doesn’t point at it: kubectl get ingress.
502 or 504 while the pods are readyThe network policy doesn’t admit your controller: set networkPolicy.apiFrom.
The live run view stays stillThe ingress buffers. The ingress

Something else

Everyone had to sign in again
Redis lost its data. No run was lost, but one in progress that could change something outside failed with Progress unknown. What Redis holds
A step failed with “Outcome unknown”
Its worker stopped without warning, such as out of memory, or Redis was down over 2 minutes. Another worker carried on from what was finished, within about 10 seconds, or about 3 minutes when the server was gone. A step that changes something outside isn’t sent again. A run whose worker stops 3 times is stopped for good. A run failed
“This address can’t be reached from workflows: …”
Outbound access
The audit log shows your proxy’s address for everyone
The address ranges to trust
Steps can’t read or save their data
Read docker compose logs seaweedfs seaweedfs-s3. The relay follows a restarted file store within a minute.
The address is gone after the server restarted
Run docker compose up -d. It never loses data; down -v does.
The License card says Embed: not in this license
Your license has no Embed. Ask GoRunner for one that does.

Still stuck?

Send GoRunner the output of docker compose ps, the last lines of the log, and the VERSION file. Never send .env: it holds your passwords.