Silent stalls, 308 self-redirect loops, missing SSE transport, and the relay's own hard timeout. How to tell them apart in 20 seconds.
This failure is so common with third-party API relays that it has a signature: you send a request, nothing happens, and around 180–195 seconds later you get a generic transport or connection error. Nothing in the logs. It is not your network.
178 to 194 seconds, suspiciously consistent, is somebody else's timer. The relay gave up upstream and never told you; your client waited out its window. You are paying three minutes per failed call.
Fix: stop waiting for it. Set your own idle timeout to ~90s so a dead call is declared dead in half the time, then retry on a fresh connection.
streamIdleTimeoutMs: 90000
retryPolicy: { maxRetries: 3, backoffMs: [800, 2000, 6000] }
This one is nastier because a health check passes: TCP connects, TLS is fine, the relay accepts the request — then writes nothing. Typically the client tried websocket first and the relay accepted the socket without implementing it, or the relay's own upstream died silently.
Fix: pin the transport. Left on auto, some clients try websocket before HTTP/SSE.
api: openai-completions
transport: sse # explicit, never auto
baseURL ends in /v1 and the relay appends another /v1, or the
edge redirects http→https forever. One command shows it:
curl -sS -o /dev/null -w '%{http_code} %{redirect_url}\n' https://relay.example.com/v1/models
A 308 with a redirect target that contains the path twice is your answer. Fix the base
URL: exactly one /v1.
Not a hang, but the other half of "it worked yesterday". The app reads an env var name
(apiKeyEnvName) that isn't set; renaming a provider means updating both the provider block
and the credential reference. Check with echo $YOUR_KEY_NAME before touching code.
LLM Relay Doctor runs six checks in order — reachability,
redirect behavior, /models with your key, a streaming completion that measures first-byte
latency, a non-streaming call, and a verdict — then prints the exact config patch for the working path.
29 USDT, no dependencies, Node 18+.
If you only remember one thing: a hang is not slowness, it is a stall. Lower the idle timeout and add failover; never sit inside someone else's 180-second timer.
One command tells you why your API / relay endpoint is broken, in 20 seconds.
Get it — 29 USDT