VIEWPORT
Troubleshooting

Relay handshake errors

For self-hosters. JWT validation fails. Noise handshake rejected. Workspaces refuse to connect.

This page is for self-hosters of the relay. If you're using the hosted relay at relay.getviewport.com, see Daemon won't connect.

First: read the relay logs

docker logs viewport-relay --tail 200
# or
curl -H "Authorization: Bearer $RELAY_ADMIN_TOKEN" https://relay.your-co.com/logs

The relay logs handshake failures with a clear reason code.

Common errors

JWT validation failed: JWKS unreachable

The relay can't reach the platform's JWKS endpoint to verify daemon tokens.

Check:

docker exec viewport-relay curl -I "$RELAY_JWKS_URL"

If that fails: network policy, DNS, or the JWKS URL is wrong. Confirm:

docker exec viewport-relay env | grep JWKS

Should match your platform's well-known endpoint, e.g., https://api.getviewport.com/api/.well-known/jwks.json for hosted control plane, or your self-hosted URL.

JWT validation failed: signature mismatch

The daemon's token was signed by a key the relay's JWKS doesn't have.

Causes:

  • The platform rotated its signing key but the relay cached an old JWKS. Fix: restart the relay. Or wait 1 hour for the cache to expire.
  • The daemon is connecting to the wrong relay (testing instance, etc.). Fix: check daemon.relay.endpoint in ~/.viewport/config.json.

JWT validation failed: token expired

The relay credential has aged out. Daemon should auto-rotate, but if it's been offline a long time the token may be past its hard expiry.

Fix: on the daemon, vpd restart. If that doesn't work, vpd unpair && vpd pair.

Noise handshake failed: invalid psk

The workspace is configured with policy_mode: crypto_pairing (Noise IKpsk2), but the daemon is connecting with plain Noise IK.

Fix:

  • If you want PSK mode: ensure the daemon was paired after the policy mode was set. Re-pair if needed.
  • If you don't want PSK mode: change the workspace policy in the web app: Settings → Security → Policy mode → Standard.

Workspace not found

The relay validated the JWT but the workspace it points at doesn't exist on this platform.

Causes:

  • The daemon is paired to a different platform than the relay is talking to.
  • The workspace was deleted.

Fix: confirm daemon.api.endpoint (control plane URL) matches RELAY_VALIDATE_URL (relay-to-platform URL).

RELAY_INTERNAL_KEY mismatch

The relay's RELAY_INTERNAL_KEY doesn't match what the platform expects on the validate endpoint.

Fix: rotate. Set the same value in both relay container env and platform config. Restart both.

frame too large

A single frame exceeded RELAY_FRAME_MAX_BYTES (default 1 MiB). The daemon should chunk large transcripts, but if you're hitting this with normal agent activity, raise the limit:

docker run -d -e RELAY_FRAME_MAX_BYTES=4194304  # 4 MiB

rate limit exceeded

The IP you're connecting from exceeded RELAY_RATE_LIMIT_PER_IP. Defaults are conservative.

Fix: raise the limit, or disable for trusted IPs by setting RELAY_RATE_LIMIT_PER_IP=0. See Reference: env vars.

Where to go next

On this page