gofr-dev/gofr · error
%w, got: %v
Error message
%w, got: %v
What it means
This is the wrapped form of errNegativeIdleConnTimeout from (*ConnectionPoolConfig).Validate, formatted with %w (errors.Is-compatible) and %v to include the offending time.Duration (e.g. "got: -5s"). It blocks applying an invalid keep-alive duration to the HTTP transport.
Source
Thrown at pkg/gofr/service/connection_pool.go:65
// IdleConnTimeout is the maximum amount of time an idle (keep-alive) connection will remain
// idle before closing itself.
// If not explicitly set (0), a default of 90 seconds will be used.
// Negative values will cause validation error.
IdleConnTimeout time.Duration
}
// Validate checks if the connection pool configuration values are valid.
func (c *ConnectionPoolConfig) Validate() error {
if c.MaxIdleConns < 0 {
return fmt.Errorf("%w, got: %d", errNegativeMaxIdleConns, c.MaxIdleConns)
}
if c.MaxIdleConnsPerHost < 0 {
return fmt.Errorf("%w, got: %d", errNegativeMaxIdleConnsPerHost, c.MaxIdleConnsPerHost)
}
if c.IdleConnTimeout < 0 {
return fmt.Errorf("%w, got: %v", errNegativeIdleConnTimeout, c.IdleConnTimeout)
}
return nil
}
// AddOption implements the Options interface to apply connection pool configuration to HTTP service.
// It modifies the underlying HTTP client's transport to use optimized connection pool settings.
func (c *ConnectionPoolConfig) AddOption(h HTTP) HTTP {
// Extract the base httpService from any wrapped service
httpSvc := extractHTTPService(h)
if httpSvc == nil {
// If we can't find the base service, return unchanged
// This maintains backward compatibility
return h
}
// Validate configuration before applying
if err := c.Validate(); err != nil {View on GitHub (pinned to 187eb24962)
Solutions
- Use 0 (default) or a positive duration for IdleConnTimeout; never negative
- Parse with time.ParseDuration and check sign immediately after loading config
- Clamp: if d < 0 { d = 0 } before building ConnectionPoolConfig
- Match with errors.Is(err, errNegativeIdleConnTimeout) for field-specific handling
Example fix
// before
pool := &ConnectionPoolConfig{IdleConnTimeout: timeout} // timeout = -30s from config
// after
timeout, _ := time.ParseDuration(cfg.IdleTimeout)
if timeout < 0 { timeout = 0 }
pool := &ConnectionPoolConfig{IdleConnTimeout: timeout} Defensive patterns
Strategy: validation
Validate before calling
d, err := time.ParseDuration(cfg.IdleTimeout)
if err != nil { return err }
if d < 0 { return fmt.Errorf("IdleConnTimeout must be >= 0, got %v", d) }
pool := &ConnectionPoolConfig{IdleConnTimeout: d} Type guard
func isNegativeIdleTimeoutErr(err error) bool { return errors.Is(err, errNegativeIdleConnTimeout) } Try / catch
if err := pool.Validate(); err != nil {
if isNegativeIdleTimeoutErr(err) {
pool.IdleConnTimeout = 0 // fall back to transport default
} else {
return fmt.Errorf("connection pool config: %w", err)
}
} Prevention
- Never encode 'no timeout' as a negative duration; use 0
- Parse and sign-check durations immediately after reading config
- Validate the full config before applying it to a service
- Use errors.Is(err, errNegativeIdleConnTimeout) and log the offending duration ('got: %v')
When it happens
Trigger: Validate() (directly or via AddOption/AddHTTPService) encounters c.IdleConnTimeout < 0, e.g. ConnectionPoolConfig{IdleConnTimeout: -time.Minute}.Validate().
Common situations: Duration parsing mistakes (missing unit, sign typo) in config/env; using -1 as a sentinel for 'no timeout' which the library does not support; overflow in duration arithmetic.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- MaxIdleConns cannot be negative
- MaxIdleConnsPerHost cannot be negative
- IdleConnTimeout cannot be negative
- %w, got: %d
- invalid FTP configuration: host and port are required
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/df572627d71fbdf8.
Report an issue: GitHub.