slimtoolkit/slim · error
dialing backend: %v
Error message
dialing backend: %v
What it means
After building the FastCGI environment, RoundTrip dials the FastCGI backend at network/address (defaulting to tcp + r.URL.Host) with the configured dial timeout. A dial failure is wrapped as "dialing backend: %v". This is the classic 'cannot reach the FastCGI process' failure and is explicitly marked as a candidate for retry.
Source
Thrown at pkg/app/master/probe/http/internal/fastcgi.go:91
env, err := t.buildEnv(r)
if err != nil {
return nil, fmt.Errorf("building environment: %v", err)
}
network, address := "tcp", r.URL.Host
if log.IsLevelEnabled(log.DebugLevel) {
envJSON, _ := json.Marshal(env)
log.Debugf("HTTP probe - FastCGI env - %s", string(envJSON))
}
ctx := r.Context()
dialer := net.Dialer{Timeout: t.DialTimeout}
fcgiBackend, err := DialWithDialerContext(ctx, network, address, dialer)
if err != nil {
// TODO: wrap in a special error type if the dial failed, so retries can happen if enabled
return nil, fmt.Errorf("dialing backend: %v", err)
}
// fcgiBackend gets closed when response body is closed (see clientCloser)
// read/write timeouts
if err := fcgiBackend.SetReadTimeout(t.ReadTimeout); err != nil {
return nil, fmt.Errorf("setting read timeout: %v", err)
}
if err := fcgiBackend.SetWriteTimeout(t.WriteTimeout); err != nil {
return nil, fmt.Errorf("setting write timeout: %v", err)
}
contentLength := r.ContentLength
if contentLength == 0 {
contentLength, _ = strconv.ParseInt(r.Header.Get("Content-Length"), 10, 64)
}
var resp *http.Response
switch r.Method {View on GitHub (pinned to 81940d17fa)
Solutions
- Verify the backend address/port in the probe URL matches what the FastCGI server listens on (netstat/php-fpm config).
- If the backend uses a unix socket, configure the transport to dial unix instead of tcp.
- Increase DialTimeout and/or add retry logic — the code comments dial failures as retryable.
- Confirm the app process is running before probing (start ordering / readiness probes).
Example fix
// before: probing tcp while php-fpm listens on a socket
// after: point the transport at the socket
t := FastCGITransport{ /* network: "unix", address: "/run/php-fpm.sock", DialTimeout: 5 * time.Second */ } Defensive patterns
Strategy: retry
Validate before calling
conn, err := net.DialTimeout("tcp", host+":"+port, 3*time.Second)
if err != nil {
return fmt.Errorf("FastCGI backend unreachable at %s:%s — start it first", host, port)
}
conn.Close() Try / catch
var resp *http.Response
err := retry(3, backoff, func() error {
var e error
resp, e = fcgiTransport.RoundTrip(req)
if e != nil && strings.Contains(e.Error(), "dialing backend") {
return e // retryable per transport comments
}
return e
}) Prevention
- Confirm the FastCGI listen address/port (php-fpm pool config) matches the probe URL.
- Use unix-socket transport config when the backend listens on a socket.
- Wait for app readiness before probing; add retry with backoff for dial errors.
- Set a reasonable DialTimeout (a few seconds) on the transport.
When it happens
Trigger: RoundTrip when DialWithDialerContext fails: backend not listening on r.URL.Host's port, wrong network type (unix vs tcp), connection refused/timeout, or context cancellation before the dial completes.
Common situations: Probing a containerized PHP app whose php-fpm listens on a unix socket but the transport dials tcp; wrong port in the probe URL; app not yet started when the probe runs; firewall or NetworkPolicy blocking the connection.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- fcgi: invalid header version
- building environment: %v
- setting read timeout: %v
- setting write timeout: %v
- invalid ws proto - %s
AI-assisted analysis of slimtoolkit/slim@81940d17fa (2026-08-31).
Data as JSON: /api/errors/314d7422e4810c9f.
Report an issue: GitHub.