Intermittent ERR_STREAM_PREMATURE_CLOSE on create-retell-llm / update-retell-llm (connection dropped before response body)

Summary
Our backend is getting connection failures when calling your LLM management API. The HTTP connection is being closed by your server before the response body is fully delivered, so our
Node.js fetch client throws ERR_STREAM_PREMATURE_CLOSE (“Premature close”). This surfaces to our users as 500 errors when creating/updating voice agents.

Affected endpoints

Exact error signature
Invalid response body while trying to fetch /create-retell-llm close
errno: ERR_STREAM_PREMATURE_CLOSE
code: ERR_STREAM_PREMATURE_CLOSE
type: system
No HTTP status code is returned — the socket is closed mid-response, so there is no 4xx/5xx from your side, just a truncated/aborted response stream.

Timeline (intermittent bursts, 2026-06-22)

  • ~14:00–14:56 UTC (09:00–09:56 COT): ~30 failures, then recovered.
  • Quiet period (no errors) until ~19:38 UTC.
  • 19:38 UTC (14:38 COT): failures resume — first occurrence at 2026-06-22 19:38:27 UTC.
  • 20:00–20:30 UTC: 6 failures.
  • 20:30–21:00 UTC (15:30–16:00 COT): 34 failures — and climbing at time of report (20:56 UTC).
  • Last 30 min split: 18× on create-retell-llm, 14× on update-retell-llm.

Other notes for your investigation

  • The failures hit multiple of our backend instances (different hostnames/PIDs), so this is not a single bad client/pod on our end.
  • 100% of these errors are ERR_STREAM_PREMATURE_CLOSE — no timeouts, no DNS/TLS errors, no 4xx/5xx. The request is sent and accepted; the response stream just terminates early.
  • Pattern is intermittent (two separate bursts with a clean recovery in between), which points to server-side connection resets rather than a hard outage.

What we’d like from you

  1. Confirm whether your create-retell-llm / update-retell-llm services experienced connection drops / instability in the windows above (UTC).
  2. Any recommended client settings on our side (keep-alive timeout, connection reuse, idempotency/retry guidance for these endpoints) to mitigate premature-close on transient resets.

Raw sample log line
{“level”:50,“time”:1782157107943,“component”:“VoiceAgentCrudController”,“error”:{“message”:“Invalid response body while trying to fetch
/update-retell-llm/llm_69ef2a8915bbec9c75fbb365ff03: Premature
close”,“type”:“system”,“errno”:“ERR_STREAM_PREMATURE_CLOSE”,“code”:“ERR_STREAM_PREMATURE_CLOSE”},“msg”:“voice_agent.crud_internal_error”}

@david4 checking with the team

Any news?
This is affecting our production environment with users

Hey @david4 we’re looking into this. In the meantime for mitigation please try:

  • Retry: treat ERR_STREAM_PREMATURE_CLOSE (and any socket close with no HTTP status) as a retryable transport error. Exponential backoff with jitter, cap ~3–5 attempts.
  • Keep-alive: set your Node HTTP agent’s keepAliveTimeout strictly lower than any upstream idle timeout in your path so the client retires pooled sockets first. We’re separately auditing our server-side defaults; until that ships, lowering the client side is the safer half of the race.
  • PATCH /update-retell-llm: naturally idempotent at the resource level. Two safe retry patterns: (a) omit If-Match for blind retry — same body produces the same result; (b) re-GET to refresh the ETag and retry, accepting a possible 412 if a concurrent writer landed in between.
  • POST /create-retell-llm: NOT idempotent — llm_id is server-generated inside the handler, so a blind retry can produce a duplicate if the first request actually persisted before the socket closed. On premature-close, call GET /list-retell-llms and reconcile by a client-side correlator (e.g. a recognizable field you set in the LLM config) before retrying.

Thank You