Skip to content

Troubleshooting

Ordered by how often it comes up

Edit this page
On this page

Ordered roughly by how often each one comes up.

Installation

docker compose up exits immediately with a variable error

A value marked REQUIRED in .env is blank. The message names it. The compose file uses the ${VAR:?} form deliberately, so a half-configured install refuses to start rather than coming up looking healthy.

The database refuses the connection string

POSTGRES_PASSWORD was generated with openssl rand -base64, which produces / and + about half the time. That value ends up inside DATABASE_URL, where those characters make an invalid URL the driver rejects outright. Use openssl rand -hex 24.

Migrations fail partway

Each migration file executes as one multi-statement query, which PostgreSQL wraps in an implicit transaction — so a failing migration rolls back whole rather than leaving half a schema. Fix the cause and re-run; the runner skips what already applied.

Sign-in

Sign-in redirects to the wrong address

BETTER_AUTH_URL does not match the URL in the browser. It must include the scheme and the port. This is the single most common issue after putting a reverse proxy in front — see TLS and reverse proxy.

The SSO callback returns "invalid state"

The state cookie did not come back. Usually a proxy stripping cookies, or a redirect URI on a different host from the one that started the flow. The cookie is scoped to /api/sso and is single-use.

A user deactivated in the directory can still sign in

They were deactivated in the provider but not in Loomscope. OIDC only tells you about people at the moment they authenticate; closing that gap is what SCIM is for.

There is no mail transport in the product, so requesting a link fails rather than silently succeeding. LOOMSCOPE_MAGIC_LINK_ECHO=true prints the link to the log — development only, since it writes a single-use credential to stdout.

Daemons

The daemon exits immediately

LOOMSCOPE_DAEMON_API_KEY is unset. A scanner that starts without credentials and never scans is worse than one that refuses to start.

The daemon will not register

In order: is the key set and correct; can the daemon reach LOOMSCOPE_SERVER_URL from inside its network namespace; does the control plane log show a 401. A 401 means the key is wrong or the daemon was deleted in the UI — re-enrol it.

The daemon connects, then nothing is scanned

A network must exist in the UI before anything is probed. Then check the daemon is online, and that the job worker is running — the scheduler is what enqueues scans.

Hosts appear and then disappear

Two daemons registered under the same name. Each LOOMSCOPE_DAEMON_NAME must be distinct.

The long poll reconnects every 30 seconds

A proxy read timeout below 60 seconds. The daemon holds /api/v1/daemon/jobs/poll open for up to a minute.

Discovery

Hosts are not being discovered

In order:

  1. Does a network exist? Nothing is scanned until one does.
  2. Is the daemon online with a recent heartbeat?
  3. Is it falling back to TCP? docker logs loomscope-daemon | grep "falling back to TCP" — if so, the sweep is probing only 80, 443 and 22.
  4. Layer-2 reachability. ARP needs adjacency.
  5. A firewall dropping ICMP and the TCP probes.

A host that answers nothing at all will not be found by active scanning. That is what SNMP, ARP tables and flow data are for.

Some hosts are found, most are not

Almost always the ICMP fallback. See above.

Scans queue but never run

No daemon is polling, or the worker is not running. Check Settings → Daemons and Settings → Jobs.

A session is stalled

The daemon stopped reporting progress mid-scan — usually the process died or lost its route. Nothing is lost; the next scheduled run picks the range back up. A daemon that stalls repeatedly is worth investigating.

Data quality

Services are detected but not identified

No signature matches. Write one — see Service signatures — and confirm it loaded by checking the custom signature count on the daemon list.

Vulnerability findings look wrong

Check the matched via column. banner is a heuristic and is where false positives concentrate: a distribution build with the fix backported still reports the upstream version, and nothing observable from the network can tell. Mark it a false positive; that is useful work rather than a workaround.

The vulnerability list looks suspiciously short

Check the feed age. A stale CVE mirror produces a short list rather than an error. In an air-gapped install the mirror is only as fresh as the last copy in.

The application topology shows no real edges

No flow data. Without it, Loomscope draws lighter co_hosted placeholder edges rather than an empty graph. Point your switches and routers at the daemon's NetFlow listeners — UDP 2055 and 6343 by default.

The L2 topology has no adjacencies

No SNMP credentials for the switches. LLDP and CDP neighbour tables are the only source for those edges.

Operations

Stored credentials fail to decrypt

LOOMSCOPE_KMS_KEY differs from the one in use when they were written. Restore the original; there is no recovery path without it. This is the failure mode that looks healthy — see Backup and restore.

Snapshots stopped

The scheduler is not running. Check Settings → Jobs for the last run of inventory.snapshot, and check the worker container is up. The 60-day density strip on History shows the gap.

Scheduled work stopped after a restart

A failed tick is retried within a run but not across a restart — a worker that died mid-retry resumes the normal schedule. Confirm the worker is running and that the next natural tick landed.

Realtime updates stopped

SSE is being buffered by a proxy. Turn response buffering off for /api/sse — see TLS and reverse proxy.

Everything is slow

Check PostgreSQL connections first. Exhaustion presents as slowness rather than as an error:

sql
SELECT count(*) FROM pg_stat_activity WHERE datname = current_database();

Then check disk. Snapshots and audit entries accumulate with no automatic pruning.

Getting help

Include, in this order: the version, the deployment shape (Compose, Helm, systemd), what you expected, what happened, and the relevant log lines with LOG_LEVEL=debug. Redact nothing — the logger already redacts credentials, API keys, community strings and session tokens.

Open an issue. Vulnerabilities go to the private channel in SECURITY.md instead.