{"record":{"id":"816f62886b8fb886","repo":"henrygd/beszel","slug":"timeout-creating-session","errorCode":null,"errorMessage":"timeout creating session","messagePattern":"timeout creating session","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/hub/transport/ssh.go","lineNumber":187,"sourceCode":"\tsessionChan := make(chan *ssh.Session, 1)\n\terrChan := make(chan error, 1)\n\n\tgo func() {\n\t\tsession, err := t.client.NewSession()\n\t\tif err != nil {\n\t\t\terrChan <- err\n\t\t} else {\n\t\t\tsessionChan <- session\n\t\t}\n\t}()\n\n\tselect {\n\tcase session := <-sessionChan:\n\t\treturn session, nil\n\tcase err := <-errChan:\n\t\treturn nil, err\n\tcase <-ctx.Done():\n\t\treturn nil, errors.New(\"timeout creating session\")\n\t}\n}\n\n// extractAgentVersion extracts the beszel version from SSH server version string.\nfunc extractAgentVersion(versionString string) (semver.Version, error) {\n\t_, after, _ := strings.Cut(versionString, \"_\")\n\treturn semver.Parse(after)\n}\n\n// RequestWithRetry sends a request with automatic retry on connection failures.\nfunc (t *SSHTransport) RequestWithRetry(ctx context.Context, action common.WebSocketAction, req any, dest any, retries int) error {\n\tvar lastErr error\n\tfor attempt := 0; attempt <= retries; attempt++ {\n\t\terr := t.Request(ctx, action, req, dest)\n\t\tif err == nil {\n\t\t\treturn nil\n\t\t}\n\t\tlastErr = err","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/henrygd/beszel/blob/b38fb7dafa60812cc22e6a84ce313e94f1ce0a32/internal/hub/transport/ssh.go#L169-L205","documentation":"createSessionWithTimeout gives up when the SSH session cannot be created before the request context is cancelled (ctx.Done() fires). Request therefore fails because the underlying SSH connection could not produce a session in time.","triggerScenarios":"sessionChan produced no session and errChan no error before ctx was done — slow SSH handshake/authentication, network stall, or a very short request timeout.","commonSituations":"Remote host unreachable or dropping packets (silent firewall drop); slow DNS; server slow to accept auth; default timeout too low for high-latency links (satellite/VPN); hub under heavy load.","solutions":["Increase the SSH request timeout / context deadline","Verify network connectivity to the host (ping, nc on the SSH port)","Check SSH server responsiveness and MaxStartups throttling on the host","Ensure DNS resolution is fast; use IP or faster resolver if needed","Retry; transient network stalls often resolve"],"exampleFix":"// before\nctx, cancel := context.WithTimeout(context.Background(), 4*time.Second)\n// after\nctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) // slow links\n","handlingStrategy":"retry","validationCode":"conn, err := net.DialTimeout(\"tcp\", host+\":22\", 5*time.Second)\nif err != nil { return fmt.Errorf(\"host unreachable: %w\", err) }","typeGuard":null,"tryCatchPattern":"data, err := client.RequestWithRetry(common.GetData, dest)\nif err != nil {\n    if strings.Contains(err.Error(), \"timeout creating session\") {\n        // backoff and retry, or mark system as unreachable\n    }\n    return err\n}","preventionTips":["Set realistic SSH timeouts for your network latency","Alert on hosts that repeatedly time out","Verify firewalls permit the SSH port; check sshd MaxStartups"],"tags":["go","ssh","timeout","network"],"backgroundTag":"connection-timeout","analyzedSha":"b38fb7dafa60812cc22e6a84ce313e94f1ce0a32","analyzedAt":"2026-08-31T15:10:10.149Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}