Troubleshooting
Symptoms first, diagnosis second. Most issues fall into one of these categories — start with the matching section.
Daemon won’t start
Section titled “Daemon won’t start”Symptom: norsk-ctl <anything> errors with a connection refused or “daemon not reachable” message.
Check, in order:
- Is the config present?
~/.norsk-ctl/config.yamlis read at boot. Missing or unparseable config means the daemon exits immediately.If missing, runTerminal window ls -l ~/.norsk-ctl/config.yamlnorsk-ctl config shownorsk-ctl init. - Is the port free? Default is
8333(override viaNORSK_CTL_PORT).Terminal window ss -tlnp | grep 8333 - systemd service running? On
--serverinstalls:Terminal window sudo systemctl status norsk-ctlsudo journalctl -u norsk-ctl -n 200 --no-pager - Docker reachable? The daemon shells out to Docker for every instance op.
docker psshould return cleanly as the same user the daemon runs as. On Linux, the daemon user must be in thedockergroup —norsk-ctl restartrefuses to bounce when the current shell isn’t in the group yet (you’d just re-create the problem).
product add rejects the license
Section titled “product add rejects the license”Symptom: norsk-ctl product add … exits non-zero (or the Add Product form shows a 400) complaining about the license file. Nothing is registered.
- “not a V2 license envelope”? The file is readable but isn’t a signed V2 envelope. Two quite different causes share this message, so check the path before assuming the license is at fault:
- The path points at the wrong thing — an HTML error page from a failed download, a truncated file, the wrong
.json.head -c 200 <file>settles it in one look. - It really is an older V1 license. Those are no longer accepted when registering a product (V2 is required) and must be reissued — contact Norsk support.
- The path points at the wrong thing — an HTML error page from a failed download, a truncated file, the wrong
- “license has no entry for product …”? The file is a valid V2 envelope but doesn’t cover this product — the message lists what it does cover. If it names the product but you still get an error, the entry covers a different image or version than the one you passed to
--image— andnorsk-ctl product add --license-file <file>with no--imageregisters exactly what the license entitles, so dropping--imageis usually the fix. - “license expired at …”? A V2 envelope carries an expiry for the license and one per product entry; either lapsing is rejected with the date. Reissue it.
- Registration succeeded but warned it “was not validated”? The daemon could not read the file (usually permissions — it runs unprivileged, while Docker mounts the license as root). Registration is allowed to proceed, but nothing was checked: if it turns out to be a V1 license, the engine rejects it at launch instead. Make the file readable by the daemon user and re-add to get a real answer.
Launch hangs or instance never reports healthy
Section titled “Launch hangs or instance never reports healthy”Symptom: instance launch-template returns, but instance describe shows status: starting for minutes.
- Image pull in progress? First launch on a fresh box pulls the studio (~1.5 GB) and media (~2 GB) images. Watch with
docker pullrunning separately orjournalctl -u norsk-ctl -f. - License rejected? Studio refuses to start without a valid license. Check the studio container logs (compose names containers
<id>-<service>-1):Terminal window docker logs <id>-studio-1 --tail 100 - Port collision. Ingest ports (SRT/RTMP/etc.) are published directly to the host. Two instances binding the same host port will fail — second one stays stuck.
- Workflow YAML invalid. A malformed workflow drops Studio into an error state. Visit
/instance/<id>/studio/in the browser; the canvas surfaces the parse error.
Proxy returns 502
Section titled “Proxy returns 502”Symptom: Public URL serves a 502 / “upstream unavailable” from nginx.
- Instance not running?
norsk-ctl instance list— does the target instance still exist? If you deleted it, the URL is dead. - Stale nginx config?
norsk-ctl proxy reloadregenerates nginx config from the daemon’s current view. Most launch/teardown paths trigger this automatically; if you hand-killed a container withdocker stop, the daemon’s view may not match reality.norsk-ctl proxy statusshows the active upstreams. - Daemon down behind the proxy? Requests to
/api/and/proxy tohost.docker.internal:8333. If the daemon stopped, the proxy survives but every backend request 502s.
Instance shows stopped but containers are still running (or vice versa)
Section titled “Instance shows stopped but containers are still running (or vice versa)”norsk-ctl tracks instance state in ~/.norsk-ctl/norsk-ctl.db. Drift happens if you docker rm containers behind its back, or if the daemon was killed mid-operation.
# What does docker think is running? Each instance is a compose# project named by its instance id.docker compose ls
# What does norsk-ctl think?norsk-ctl instance listIf they diverge: norsk-ctl instance restart <id> reconciles by tearing down and re-launching. norsk-ctl instance delete <id> followed by a fresh launch is the heavy-handed reset.
Plugins aren’t discovered
Section titled “Plugins aren’t discovered”Symptom: the Studio product’s plugin listing (GET /products/norsk-studio/api/plugins?workingDirectory=…) doesn’t show a plugin you’ve dropped under <workingDirectory>/plugins/.
- Missing
package.json? Discovery requires a readablepackage.jsonwith a non-emptynamefield. Directories without one are skipped with a warning. - Wrong working directory. Every plugin endpoint takes an explicit
workingDirectory— there’s no daemon-side default. Check the path you passed matches where the plugin actually lives. - Plugin not in the instance? Instances only load plugins baked into the image (pinned by the product template) or listed in the product template’s
server.library. Dropping files underplugins/alone doesn’t affect a launch. See Manage plugins.
Studio loads a blank canvas
Section titled “Studio loads a blank canvas”- Workflow YAML missing? The workflow save-file ships with the product template. If the product template references a save file that isn’t present in the working directory, Studio silently lands on an empty canvas. Check
instance describeand the product template’s bundled save files. - Library not loaded. Workflows reference nodes from named libraries. If the workflow uses a node from a package the product template’s library list doesn’t include, the canvas loads but the node is broken. See Studio libraries.
TLS browser warning persists after mkcert -install
Section titled “TLS browser warning persists after mkcert -install”macOS browsers cache trust decisions per-session. Fully quit and restart the browser (cmd-Q, not just close window). Firefox uses its own cert store — brew install nss before mkcert -install so Firefox is reached too.
Public IP couldn’t be auto-detected at install
Section titled “Public IP couldn’t be auto-detected at install”Symptom: install.sh --ip auto aborts with couldn't auto-detect a public IP.
--ip auto probes https://api.ipify.org then https://ifconfig.me (each 5-second timeout). If neither responds, pass --ip <host> or --public-host <name> explicitly. On a private network without outbound HTTPS, this is expected.
How to gather diagnostics
Section titled “How to gather diagnostics”When in doubt, capture:
norsk-ctl status(orstatusvia MCP)norsk-ctl config shownorsk-ctl instance listandinstance describe <id>for the affected instancejournalctl -u norsk-ctl -n 500 --no-pagerdocker compose lsanddocker logs <id>-<service>-1for any wedged containers
The web UI’s Logs view surfaces studio + media + proxy logs without the docker CLI.