{"record":{"id":"1cfdb2a9582d6591","repo":"gofr-dev/gofr","slug":"unable-to-connect-to-server-at-host","errorCode":null,"errorMessage":"unable to connect to server at host","messagePattern":"unable to connect to server at host","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/service/circuit_breaker.go","lineNumber":19,"sourceCode":"package service\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n)\n\n// circuitBreaker states.\nconst (\n\tClosedState = iota\n\tOpenState\n)\n\nvar (\n\t// ErrCircuitOpen indicates that the circuit breaker is open.\n\tErrCircuitOpen                        = errors.New(\"unable to connect to server at host\")\n\tErrUnexpectedCircuitBreakerResultType = errors.New(\"unexpected result type from circuit breaker\")\n)\n\n// CircuitBreakerConfig holds the configuration for the circuitBreaker.\ntype CircuitBreakerConfig struct {\n\tThreshold int           // Threshold represents the max no of retry before switching the circuit breaker state.\n\tInterval  time.Duration // Interval represents the time interval duration between hitting the HealthURL\n}\n\n// circuitBreaker represents a circuit breaker implementation.\ntype circuitBreaker struct {\n\tmu           sync.RWMutex\n\tstate        int // ClosedState or OpenState\n\tfailureCount int\n\tthreshold    int\n\tinterval     time.Duration\n\tlastChecked  time.Time\n\tmetrics      Metrics","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/service/circuit_breaker.go#L1-L37","documentation":"ErrCircuitOpen is the sentinel error returned by the HTTP service's circuit breaker when the circuit is in the OpenState: recent failures exceeded the configured Threshold, so the client short-circuits and refuses to send requests until the reset/health interval elapses. The misleading message ('unable to connect to server at host') actually means the request was blocked locally by the breaker, not attempted and refused.","triggerScenarios":"Calling doRequest/executeWithCircuitBreaker on an HTTP service (created via NewHTTPService with circuit breaker options) after Threshold consecutive failures have tripped the breaker; the breaker stays open until the Interval passes and a health check (HealthURL) succeeds, moving it to HalfOpen/Closed.","commonSituations":"A downstream service is down or timing out and keeps failing health checks; Threshold set too low so a brief blip trips the breaker; Interval too long so the circuit stays open and all calls fail fast with this error; integration tests exercising the breaker.","solutions":["Check downstream service health and restore it; the breaker will close once the health endpoint succeeds after Interval","Tune CircuitBreakerConfig: raise Threshold for transient-error tolerance and shorten Interval for faster recovery","Use errors.Is(err, ErrCircuitOpen) to implement caller-side fallback/caching while the circuit is open","Monitor/logs the breaker state transitions to find why requests keep failing before the trip"],"exampleFix":"// before\ncfg := &CircuitBreakerConfig{Threshold: 2, Interval: 5 * time.Minute}\n// after (tolerate more failures, recover faster)\ncfg := &CircuitBreakerConfig{Threshold: 5, Interval: 30 * time.Second, Timeout: 2 * time.Second, HealthURL: svcURL + \"/.well-known/health\"}","handlingStrategy":"retry","validationCode":"cfg := &CircuitBreakerConfig{Threshold: 5, Interval: 30 * time.Second, Timeout: 2 * time.Second, HealthURL: baseURL + \"/health\"}\nif cfg.Threshold <= 0 || cfg.Interval <= 0 {\n    return errors.New(\"circuit breaker misconfigured\")\n}\n_ = service.AddOption(cfg)","typeGuard":"func isCircuitOpen(err error) bool { return errors.Is(err, ErrCircuitOpen) }","tryCatchPattern":"resp, err := svc.Get(ctx, url)\nif err != nil {\n    if errors.Is(err, ErrCircuitOpen) {\n        return serveFallbackFromCache(ctx) // don't retry immediately\n    }\n    return err\n}","preventionTips":["Use errors.Is(err, ErrCircuitOpen) rather than string comparison (message is misleading)","Monitor downstream health so the breaker closes quickly after recovery","Tune Threshold/Interval/Timeout to your downstream's failure profile","Implement a fallback/cached response path for when the circuit is open","Check the HealthURL actually returns 2xx in the target environment"],"tags":["circuit-breaker","network","resilience","http-client"],"backgroundTag":"circuit-breaker-open","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}