Introduction
Go HTTP client connection pool runs out of available connections when response bodies are not properly closed or pool configuration is insufficient. This guide provides step-by-step diagnosis and resolution with specific commands and code examples.
Symptoms
Typical symptoms and error messages when this issue occurs:
Get "https://api.example.com": dial tcp 10.0.0.1:443: connect: connection refused
http: no connections available in poolObservable indicators: - Application logs show connection or operation failures - Error messages appear in system or application logs - Related dependent services may exhibit cascading failures
Common Causes
- 1.The connection pool exhaustion typically occurs when:
- 2.Response bodies are not closed after reading
- 3.MaxIdleConnsPerHost is set too low
- 4.Connection timeout is not configured
Step-by-Step Fix
Step 1: Check Current State
lsof -p $(pgrep app) | grep TCP | wc -lStep 2: Identify Root Cause
netstat -an | grep ESTABLISHED | wc -lStep 3: Apply Primary Fix
```go // Always close response body resp, err := client.Get(url) if err != nil { return err } defer resp.Body.Close() // Critical: must close
// Read entire body to allow connection reuse body, _ := io.ReadAll(resp.Body) ```
Apply this configuration and restart the application:
go build && ./applicationStep 4: Apply Alternative Fix (If Needed)
// Configure proper pool settings
transport := &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
}
client := &http.Client{
Transport: transport,
Timeout: 30 * time.Second,
}After applying this configuration, verify the connection pool behavior under load testing.
Step 5: Verify the Fix
After applying the fix, verify with:
curl -v https://api.example.com/health && echo "Success"Expected output should show successful operation without errors.
Common Pitfalls
- Forgetting to close response bodies
- Setting MaxIdleConnsPerHost too low
- Not handling connection errors gracefully
Best Practices
- Always use defer resp.Body.Close()
- Configure reasonable timeouts (30s default)
- Monitor connection pool metrics
Related Issues
- Go Context Deadline Exceeded
- Go TLS Certificate Verification Failed
- Go DNS Resolution Failed