# Troubleshooting

Each entry starts from what you see. For every status and reason code, see [Errors](/docs/browser/reference/errors/).

## The verdict fetch always returns `404`

- **The page and the backend use different `sessionRef` values.** Log the value you pass to `start()` and the value you fetch, and compare them.
- **The fetch runs more than 2 minutes after the collection.** Fetch right after `ready()` resolves.
- **The collection never reached Octet.** Check the browser console for a rejected `ready()`, and look up its status in [Errors](/docs/browser/reference/errors/).
- **The edge's license and your read token belong to different licenses.** A read token reads only the verdicts that arrived under its own license.

## The browser console shows a CORS error

The page's origin isn't in the edge's `ALLOWED_ORIGIN`. Add the exact origin, including the scheme and any port, for example `https://www.example.com`, and restart the edge.

## Every session gets `401` or `403` from the edge

Octet refused your license token or your edge's client certificate. The `reason` in the edge's response, and in the edge's log, says which. See [Reasons Octet gives your edge](/docs/browser/reference/errors/#reasons-octet-gives-your-edge).

## Every session gets `400` with `unsealed_bundle`

The page serves a collector older than v1.3.0, which Octet no longer accepts. Download the current `octet-collector.js` and its `octet-collector.js.sri`, and serve both from your origin. See [Embed the Collector](/docs/browser/integration/embed-collector/).

## Honest users get `medium` or `high`

Check that nothing terminates TCP or TLS in front of the edge. A proxy, application load balancer or CDN in front of the edge makes every user look as if they were connecting through that device. See [Deploy the Edge](/docs/browser/integration/deploy-edge/#nothing-may-terminate-tls-or-tcp-in-front-of-the-edge).

If the edge is set up correctly and a specific honest session still gets `medium` or `high`, send its `sessionRef` and time to [developer@octetproof.com](mailto:developer@octetproof.com).

## Every verdict has the same country, the one where my servers are

Something in front of the edge is replacing the user's IP address with its own. The edge takes the IP address from the TCP connection and ignores forwarded headers. Remove the device, or switch it to layer 4 passthrough.

## VPN sessions come back as `none`

- Check that the page runs in `full` mode, the default. `lite` and `passive` give Octet less evidence.
- Check that your CSP allows the hosts for your mode and `worker-src blob:`. See [Network and CSP](/docs/browser/reference/network/).
- Octet does not flag every masked session.

## `ready()` is slow

- Call `start()` at page load, not at the moment of action, so that the collection is done by the time the user acts.
- In `full` mode, a connection tunnelled to an exit far from the user can take up to about 4.5 seconds. `lite` is usually faster.

## The collector script doesn't load

- Serve `octet-collector.js` from your own origin. A `src` that points at the GitHub release URL won't load.
- Check that the `integrity` value is the exact contents of `octet-collector.js.sri` from the same release as the script. A mismatch blocks the script.
- Check that your `script-src` allows the path you serve it from.

## The edge log says `plain HTTP`

`EDGE_TLS_CERT_FILE` or `EDGE_TLS_KEY_FILE` is unset, so the edge is serving HTTP. Set both and restart. See [Edge Configuration](/docs/browser/reference/edge-config/).

## The edge doesn't start

The edge refuses to start without its client certificate and key, `EDGE_CLIENT_CERT_FILE` and `EDGE_CLIENT_KEY_FILE`, or with an `OCTET_URL` that isn't `https://`. Run `sudo journalctl -u octet-edge -n 20`. The last line names what is missing, for example `mTLS to octet is required, set EDGE_CLIENT_CERT_FILE, EDGE_CLIENT_KEY_FILE`. To get the files, see [Deploy the Edge](/docs/browser/integration/deploy-edge/#4-install-the-client-certificate).

## Our auditor wants to check our verdicts

Give the auditor your stored tokens, the Octet keys you kept, and the check in [Keep Verdicts for Audit](/docs/browser/integration/keep-verdicts/). The auditor needs no Octet account.

## Still stuck

Email [developer@octetproof.com](mailto:developer@octetproof.com) with the `sessionRef`, the time of the request, and the status and reason code you saw. Never send a license token, read token or private key.
