mirror of
https://github.com/MeshCore-Beacon/beacon-docs.git
synced 2026-10-23 21:33:59 +00:00
132 lines
7.6 KiB
Markdown
132 lines
7.6 KiB
Markdown
# Troubleshooting
|
|
|
|
Each heading is a symptom. Under it: the usual cause, then the fix.
|
|
|
|
## `docker compose up` fails with `403 Forbidden` pulling an image
|
|
|
|
The error looks like `... manifests/<tag>: 403 Forbidden`. The GHCR package has been switched,
|
|
or defaulted, to private. A maintainer has to set it back to public; the steps are under
|
|
[Maintainers: publishing images](../README.md#maintainers-publishing-images). Nothing on your
|
|
side fixes it.
|
|
|
|
## Everyone is getting 429
|
|
|
|
Beacon rate limits per client IP, and behind a proxy every visitor arrives from the proxy's
|
|
address unless Beacon is told otherwise. Two things have to be true:
|
|
|
|
1. `server.trusted_proxies` in `config.yaml` lists the proxy's address as a CIDR: `/32` for one
|
|
IPv4 host, `/128` for one IPv6 host, `172.30.0.0/24` for the all-in-one compose network. A
|
|
bare address stops startup with `failed to load config ... netip.ParsePrefix("10.0.0.5"): no '/'`.
|
|
2. The proxy overwrites `X-Real-IP` with the connecting client's address. The shipped Caddy,
|
|
nginx and Apache configs do; see [Reverse proxy](reverse-proxy.md).
|
|
|
|
Beacon logs a warning at startup when limits are on and no proxy is trusted. The same mistake
|
|
makes the WebSocket connection cap (5 per IP) hit for everyone at once.
|
|
|
|
## The page loads but nothing is live
|
|
|
|
The browser could not open the WebSocket. Open the browser's developer tools, Network tab,
|
|
filter `WS`, and look at the `/ws` request. Causes, most common first:
|
|
|
|
- The proxy is not passing the upgrade, or sends the upstream address as `Host`. nginx needs
|
|
`proxy_http_version 1.1`, the `Upgrade` and `Connection` headers, and
|
|
`proxy_set_header Host $host`.
|
|
- The web app is served from a different host than the API and that origin is not in
|
|
`websocket.allowed_origins`.
|
|
- The per-IP connection cap is being hit because every visitor looks like the proxy. See the
|
|
429 item above.
|
|
- `VITE_WS_URL` points at the wrong place. It must be the public `wss://` address, not
|
|
`localhost`.
|
|
|
|
## Caddy never gets a certificate
|
|
|
|
`docker compose logs caddy` shows ACME errors. Either DNS for `DOMAIN` is not pointing at this
|
|
server yet, or ports 80 and 443 are not reachable from the internet. Fix that and Caddy
|
|
retries on its own.
|
|
|
|
## Startup fails with `database schema predates Beacon 2.0.0`
|
|
|
|
The database was created by Beacon 1.x. 2.0.0 cannot migrate it. Move the old data directory
|
|
aside and start with an empty one; see
|
|
[Upgrading](upgrading.md#upgrading-to-200-from-1x).
|
|
|
|
## Startup fails on a config value
|
|
|
|
Beacon refuses to run with a setting it cannot honour. The message names the key:
|
|
|
|
| Message | Fix |
|
|
|---|---|
|
|
| `scope "x" needs a region` | Add `region: <slug>` to that `scopes:` entry. |
|
|
| `scope "x" region "y" is not a configured region` | Use a slug that appears under `regions:`. |
|
|
| `netip.ParsePrefix("10.0.0.5"): no '/'` | Write `10.0.0.5/32`, not `10.0.0.5`. An empty entry fails with `server.trusted_proxies[0] must be a valid CIDR` instead. |
|
|
| `packets.retention must be at least 24h` | Raise it. Same for `analytics.rollup_retention`. |
|
|
| `meshmapper.scopes.refresh_interval must be between 1h and 24h` | Set it inside that range. Repeaters is also 1h to 24h; zones and channels intervals are 24h to 168h. |
|
|
| `nodes.mark_foreign requires an iatas.*.borderFile or meshmapper.zones` | Add a border source or turn `mark_foreign` off. |
|
|
| `not a well-formed GeoJSON Feature`, `ring 0 is not closed`, `geometry must be Polygon or MultiPolygon` | The border file is invalid. It must be a single GeoJSON Feature with a closed Polygon or MultiPolygon in longitude, latitude order. |
|
|
| `log level must be debug, info, warn or error` | Check `log.level` and `LOG_LEVEL`. `log format must be text or json` is the same for format. |
|
|
| `auth.api_key / BEACON_API_KEY must be at least 16 characters` | Use a longer key, with no whitespace inside it. |
|
|
|
|
## No packets are arriving
|
|
|
|
Check `GET /api/v1/brokers` first.
|
|
|
|
- **A broker shows disconnected.** `MQTT_BROKER_1_URL` must be the WebSocket endpoint,
|
|
usually `wss://host:443`, and the username and password must be a subscriber account on that
|
|
broker. `docker compose logs app` shows the connect error. See
|
|
[Getting packets in](getting-packets-in.md).
|
|
- **Connected but nothing stored.** No observers are publishing to that broker, or
|
|
`ingest.allow_countries` / `allow_continents` in `config.yaml` is filtering them out.
|
|
`GET /api/v1/observers` shows who Beacon has heard from.
|
|
- **Packets arrive but with no signal data.** The account is Role 3, which strips `snr` and
|
|
`rssi`. Ask for a Role 2 account.
|
|
|
|
## Every path hop says `"confidence": "none"`
|
|
|
|
Path resolution needs to know which nodes exist, and Beacon learns that from adverts. On a
|
|
fresh database every hop is `none` and `supportsMultibytePaths` is `false` until nodes have
|
|
advertised. This fills in on its own as the mesh is observed.
|
|
|
|
## Channel messages show a hash but no text
|
|
|
|
The channel's key is not configured, or it was added without a restart. Add it under
|
|
`channel_keys:` in `config.yaml` and run `docker compose restart app`. On start, Beacon decrypts
|
|
the stored messages for the new key and logs
|
|
`config: backfilled N previously-undecrypted channel message(s)`.
|
|
|
|
## MeshMapper imports are unconfigured or stale
|
|
|
|
Read `docker compose logs app` for `component=meshmapper`, `meshmapper.zones`,
|
|
`meshmapper.scopes`, `meshmapper.channels`, or `meshmapper.repeaters`. Refresh records include `last_error`,
|
|
`next_attempt`, and, for regional imports, `checked_at`.
|
|
|
|
| Message | Fix |
|
|
|---|---|
|
|
| `unconfigured: MeshMapper API key is missing` | Set `MESHMAPPER_API_KEY` in the backend environment. An explicitly empty environment value overrides a YAML key. |
|
|
| `unconfigured: MeshMapper API key contains invalid characters` | Re-enter the key supplied by your local MeshMapper regional or grouped-region admin; remove embedded whitespace or control characters. |
|
|
| `authentication failed (HTTP 401)` | Check that you are using the correct regional or grouped-region API key and that MeshMapper Server supports `X-API-Key`. Do not use the mobile App key. |
|
|
| `permission denied (HTTP 403)` | Ask the MeshMapper admin to check access to the requested API and IATA. A group key needs every member IATA, including members added by `import_groups`. |
|
|
| `HTTP 429` or `HTTP 503` | Wait until `next_attempt`. Beacon honours longer `Retry-After` delays and its existing refresh limits. Do not shorten polling intervals or repeatedly restart to force a request. |
|
|
|
|
After changing `.env`, run `docker compose up -d --force-recreate app` from the backend
|
|
deployment folder. A plain restart does not reload container environment variables.
|
|
Persisted backoff still applies after a restart. Never paste the key into logs, URLs, or
|
|
support messages.
|
|
|
|
Beacon keeps the last successful cached data and freshness timestamp after a failed
|
|
refresh, including an authentication failure. It does not replace imports with empty
|
|
lists or retry anonymously. See [MeshMapper API key](configuration.md#meshmapper-api-key)
|
|
for setup and rollout requirements.
|
|
|
|
## Backup export refuses a saved MeshMapper key
|
|
|
|
Move the key from `meshmapper.api_key` to `MESHMAPPER_API_KEY` in the backend environment,
|
|
clear the saved YAML value, and recreate `app`. Backups include saved YAML verbatim, so
|
|
exports refuse a nonempty MeshMapper key there to keep it out of download responses.
|
|
See [Backup and export](backup-export.md#requirements-and-limits).
|
|
|
|
## I changed a `VITE_*` value and nothing changed
|
|
|
|
Run `docker compose up -d web` (`docker compose up -d beacon-web` in the split deployment). The web container writes the values to `/config.js` when it
|
|
starts, so an edited `.env` does nothing until the container is recreated. Then hard-refresh
|
|
the page.
|