You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
An unreachable LLM host hangs flow setup for about 7 minutes with nothing in the logs #460
GetHTTPClient (backend/pkg/system/utils.go) builds its own http.Transport without a DialContext or a TLSHandshakeTimeout, so connecting to a host that never answers is bounded only by the OS SYN timeout (about 2m10s on Linux). HTTP_CLIENT_TIMEOUT (#205) caps the whole request at 600s by default, but it doesn't help here: each attempt stalls for minutes before it even connects.
Flow setup (primary image, language, flow title) goes through retryTransient (backend/pkg/providers/retry.go), which makes 3 attempts 5s apart and logs nothing for a failed attempt. When the LLM endpoint is unreachable (network down, wrong OPEN_AI_SERVER_URL, a firewall dropping packets), a new flow sits at "untitled" for about 7 minutes and docker logs pentagi stays silent until the final error. The same client is used by every LLM provider, the embedder and the search tools.
Steps to Reproduce
Point the LLM at a host that drops packets (for example set OPEN_AI_SERVER_URL to an address that never answers).
Create a flow.
The flow stays at "untitled" with nothing in the logs, then fails after about 7 minutes.
Measured with the OpenAI provider against a SYN-blackholed address: 2m14s per attempt, 6m53s total, and the only log line was the final one.
Logs
level=error msg="failed to prepare a flow" error="failed to get flow provider: failed to select primary docker image via llm call: gave up after 3 attempts: request timeout: network operation exceeded timeout" flow_id=7
Expected Behavior
Connecting fails within a bounded time, the same 30s dial and 10s TLS handshake bounds that http.DefaultTransport uses, and each failed attempt shows up in the logs. A slow answer from a reachable model should still only be bounded by HTTP_CLIENT_TIMEOUT.
Good catch — the root cause is clear: GetHTTPClient builds a Transport without DialContext/TLSHandshakeTimeout, so the effective connect bound is the OS SYN timeout (~2m10s) rather than anything HTTP_CLIENT_TIMEOUT controls, and retryTransient's 3 attempts turn that into ~7 minutes of silence. Matching http.DefaultTransport's 30s dial / 10s TLS handshake bounds is the right fix.
Two small suggestions on top of #461: (1) when logging each failed attempt in retryTransient, include the attempt index and elapsed time for that attempt — that would make network-path debugging much easier (is it the first hop, the TLS handshake, or a slow response that stalls?); (2) consider logging once before the first attempt with the target URL so a misconfigured OPEN_AI_SERVER_URL is visible in the logs immediately instead of only after the final failure.
Activity
XinwangTao commentedon Oct 18, 2026
Good catch — the root cause is clear: GetHTTPClient builds a Transport without DialContext/TLSHandshakeTimeout, so the effective connect bound is the OS SYN timeout (~2m10s) rather than anything HTTP_CLIENT_TIMEOUT controls, and retryTransient's 3 attempts turn that into ~7 minutes of silence. Matching http.DefaultTransport's 30s dial / 10s TLS handshake bounds is the right fix.
Two small suggestions on top of #461: (1) when logging each failed attempt in retryTransient, include the attempt index and elapsed time for that attempt — that would make network-path debugging much easier (is it the first hop, the TLS handshake, or a slow response that stalls?); (2) consider logging once before the first attempt with the target URL so a misconfigured OPEN_AI_SERVER_URL is visible in the logs immediately instead of only after the final failure.