Tunnels — troubleshooting
Each section heading below is a verbatim error message (or symptom) the Tunnel produces. Search by copying a unique phrase from your logs (sudo journalctl -u conduit-tunnel). Errors are designed to name what’s wrong + WHERE to fix.
The Tunnel’s messages are in this first section. If you run the legacy v1 Docker container, its (different) error strings are in Legacy: v1 Docker container errors at the bottom.
FATAL: RELAY_URL env var is required
Section titled “FATAL: RELAY_URL env var is required”Boot found no RELAY_URL.
Fix:
- Confirm
/etc/conduit-tunnel/envcontains theRELAY_URLyour operator gave you (productionwss://conduit-wss.wyre.ai, stagingwss://staging-wss.conduit.wyre.ai). - Confirm the unit references it:
EnvironmentFile=/etc/conduit-tunnel/env, thensudo systemctl daemon-reload.
FATAL: RELAY_URL must be wss://
Section titled “FATAL: RELAY_URL must be wss://”Your RELAY_URL isn’t wss://. Plain non-TLS ws, http://, and https:// are all rejected at boot — TLS is not optional.
Fix: correct the scheme to wss://.
FATAL: ENROLLMENT_TOKEN env var is required
Section titled “FATAL: ENROLLMENT_TOKEN env var is required”Boot found no ENROLLMENT_TOKEN.
Fix: confirm /etc/conduit-tunnel/env contains ENROLLMENT_TOKEN=<jwt>. If your token expired, get a fresh one from your Conduit operator.
FATAL: CAPABILITIES is not a conduit-tunnel setting
Section titled “FATAL: CAPABILITIES is not a conduit-tunnel setting”You set a CAPABILITIES env var. The Tunnel removed it on purpose: capabilities are managed in Conduit and pushed down the tunnel, not declared on the host. This guard stops a legacy v1 .env from being pasted onto a v2 host and quietly doing the wrong thing.
Fix: remove CAPABILITIES from /etc/conduit-tunnel/env. Your operator enables connectors in Conduit. (If you actually intend to run the old model, that’s the legacy container, not this Tunnel.)
relay rejected registration (reason invalid_identity / revoked_identity)
Section titled “relay rejected registration (reason invalid_identity / revoked_identity)”The relay refused your enrollment token. Reconnecting won’t help until the token is fixed — the Tunnel stops rather than hammer the relay.
Common causes:
- Token from the wrong environment (a staging token dialed at the prod relay, or vice versa).
- Token expired between mint and start.
- Token truncated on paste.
Fix: get a fresh token from your operator, minted for the same environment your RELAY_URL points at, and re-paste it cleanly into /etc/conduit-tunnel/env.
relay transient_unavailable at registration
Section titled “relay transient_unavailable at registration”The relay hit a transient server-side problem registering your tunnel (not your fault, not your token). The Tunnel retries automatically with backoff.
Fix: none needed — it will come up on its own. If it persists for more than a few minutes, tell your Conduit operator.
Tunnel registers but /v1/mcp calls return Unknown vendor
Section titled “Tunnel registers but /v1/mcp calls return Unknown vendor”The relay accepted your registration, but Conduit’s on-prem fork found no matching connector for the requesting user’s org.
Fix:
- Confirm your operator has enabled and configured the connector you’re calling (you should see
config appliedwith its slug in the Tunnel logs). - Confirm the requesting user’s primary org is the org your tunnel enrolled against — Conduit routes to the user’s primary (oldest) org’s tunnel.
- If the Tunnel just restarted, wait ~60s: config re-pushes automatically, and until it lands the Tunnel is serving nothing.
Tunnel logs config applied with an error, or a connector is missing from the applied set
Section titled “Tunnel logs config applied with an error, or a connector is missing from the applied set”Conduit pushed config, but the Tunnel couldn’t apply one of the connectors (partial apply). The applied list shows what IS serving; the error names the first failure.
Common causes:
- A malformed connector config (e.g. an
mssqlblock missinghostordatabase). - A slug this Tunnel binary version doesn’t know.
Fix: check the Tunnel logs for the apply error, then have your operator correct the config and push again. Note: a temporarily unreachable database does NOT block apply — the mssql pool connects lazily, and the first query surfaces the connectivity error instead.
mssql: only SELECT/WITH queries are allowed
Section titled “mssql: only SELECT/WITH queries are allowed”A query call tried a write, DDL, or multi-statement batch. The mssql connector is read-only by design — see the SQL Server guide.
Fix: working as intended. Reads (SELECT/WITH) only; writes go through the application layer.
Tunnel goes offline intermittently
Section titled “Tunnel goes offline intermittently”Likely causes:
- Egress firewall closing idle outbound connections (the WSS is long-lived).
- DNS resolution failure for
RELAY_URL.
Fix:
- Allow outbound
:443to your WYRE relay host. sudo journalctl -u conduit-tunnel -fshows reconnect attempts; the Tunnel reconnects with backoff and Conduit re-pushes config on reconnect.
Access denied: You do not have access to <connector> in this organization.
Section titled “Access denied: You do not have access to <connector> in this organization.”The tunnel is fine — this is Conduit’s normal access-grant enforcement, and
a freshly enabled connector is granted to no one. Grant the connector’s slug to
the calling member/team in the org’s access editor. Its sibling,
Tool "<name>" requires a higher access tier than your grants permit., means
the grant exists but at too low a tier — note that unclassified tools of a
proxied MCP server fail closed to the admin tier by design.
See Granting access.
On-prem vendor (Via Tunnel) connections
Section titled “On-prem vendor (Via Tunnel) connections”no online connector site for this org
Section titled “no online connector site for this org”The save was refused because Conduit sees no live tunnel for the org. Check Connections → Tunnels — bring the tunnel online (or fix its enrollment token) and save the connection again.
Saved, but nothing answered at the server URL through the Tunnel yet
Section titled “Saved, but nothing answered at the server URL through the Tunnel yet”Not an error — the connection is saved, but the post-save reachability probe got no answer from your server. In order of likelihood:
- The Tunnel hadn’t ACKed the allowlist push yet — wait a minute and check the tunnel’s page.
- Wrong LAN URL or port — remember it must be the address as seen from the Tunnel host.
- The vendor server is down, or a host firewall blocks the Tunnel host.
- TLS: the probe’s detail text names a certificate error → the server’s CA isn’t the PEM you pasted (or none was). Fix the Private CA certificate on the connection rather than disabling verification.
url "…" is not on the allowlist
Section titled “url "…" is not on the allowlist”The bridge refused to reach a URL no Via-Tunnel connection covers. This is the security model working. If it’s a URL you did configure, the allowlist entry and the request URL differ in scheme/host/port — re-save the connection with the exact base URL the vendor integration calls.
lanBaseUrl must be an absolute http(s) URL
Section titled “lanBaseUrl must be an absolute http(s) URL”The server URL must be absolute (https://cw.internal), not a bare hostname
or a path.
http-bridge config: caCertPem for "…" contains no valid PEM certificate
Section titled “http-bridge config: caCertPem for "…" contains no valid PEM certificate”(Tunnel-host log.) The pasted CA text isn’t parseable PEM — re-paste the full
-----BEGIN CERTIFICATE----- block, including the header/footer lines.
Still stuck
Section titled “Still stuck”Contact your Conduit operator with:
- The verbatim error from
sudo journalctl -u conduit-tunnel. - Your environment (production / staging).
- Your org ID.
- Never the
ENROLLMENT_TOKENvalue itself.
Legacy: v1 Docker container errors
Section titled “Legacy: v1 Docker container errors”These are the error strings from the v1 conduit-onprem-gateway Docker container, which is still supported for already-deployed sites. New deployments use the Tunnel above. Read container logs with docker compose logs onprem-gateway.
FATAL: CAPABILITIES env var is required
Section titled “FATAL: CAPABILITIES env var is required”The v1 container requires CAPABILITIES (this is the opposite of the Tunnel, which rejects it). Confirm .env contains CAPABILITIES=echo (or your granted list) — byte-for-byte, case-sensitive, matching what the token grants.
FATAL: ENROLLMENT_TOKEN structure invalid — expected 3 segments / — header or payload is not valid base64url
Section titled “FATAL: ENROLLMENT_TOKEN structure invalid — expected 3 segments / — header or payload is not valid base64url”The v1 container’s structural-validate rejected the token shape. Cause is copy-paste truncation/corruption — re-paste the full JWT (exactly two . separators, three base64url segments).
FATAL: ENROLLMENT_TOKEN iss claim mismatch / aud claim mismatch
Section titled “FATAL: ENROLLMENT_TOKEN iss claim mismatch / aud claim mismatch”The v1 token was minted for a different environment (or a misconfigured issuer/audience). Use a token minted for the environment your RELAY_URL points at.
assertNoInbound / assertSecureRelayUrl
Section titled “assertNoInbound / assertSecureRelayUrl”Same invariants as the Tunnel — no inbound listener, wss:// only. With the stock v1 image these should not fire unless something in the environment forces a listener or a non-TLS URL.
Verifying the legacy image
Section titled “Verifying the legacy image”The v1 container image is cosign-signed — see Quickstart → Verifying the legacy image. A failed verify means the image is NOT from WYRE’s published pipeline — do NOT deploy.

