gofr-dev/gofr · error

%w, got: %d

Error message

%w, got: %d

What it means

This is the wrapped form of errNegativeMaxIdleConns produced by (*ConnectionPoolConfig).Validate: fmt.Errorf("%w, got: %d", ...) so the sentinel remains checkable with errors.Is while including the offending MaxIdleConns value. It fires before the pool settings are applied to the HTTP transport.

Source

Thrown at pkg/gofr/service/connection_pool.go:57

	// MaxIdleConnsPerHost controls the maximum idle (keep-alive) connections to keep per-host.
	// This is the critical setting for microservices making frequent requests to the same host.
	// If set to 0, Go's DefaultMaxIdleConnsPerHost (2) will be used.
	// Negative values will cause validation error.
	// Default Go value: 2 (which is often insufficient for microservices)
	// Recommended: 10-20 for typical microservices, higher for high-traffic services
	MaxIdleConnsPerHost int

	// 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)

View on GitHub (pinned to 187eb24962)

Solutions

  1. Correct the config value so MaxIdleConns >= 0
  2. Clamp with max(0, v) before constructing ConnectionPoolConfig
  3. Call Validate() right after loading config to fail fast at startup
  4. Match with errors.Is(err, errNegativeMaxIdleConns) for precise field-level error messages

Example fix

// before
if err := pool.Validate(); err != nil { return err } // MaxIdleConns: -10
// after
pool.MaxIdleConns = max(pool.MaxIdleConns, 0)
if err := pool.Validate(); err != nil { return fmt.Errorf("invalid pool config: %w", err) }
Defensive patterns

Strategy: validation

Validate before calling

pool := &ConnectionPoolConfig{MaxIdleConns: v}
if err := pool.Validate(); err != nil {
    if errors.Is(err, errNegativeMaxIdleConns) {
        return fmt.Errorf("config: MaxIdleConns invalid: %w", err)
    }
    return err
}

Type guard

func isNegativeMaxIdleConnsErr(err error) bool { return errors.Is(err, errNegativeMaxIdleConns) }

Try / catch

if err := pool.Validate(); err != nil {
    if isNegativeMaxIdleConnsErr(err) {
        return fallbackWithDefaults()
    }
    return fmt.Errorf("connection pool config: %w", err)
}

Prevention

When it happens

Trigger: Validate() (invoked directly or through AddOption when configuring AddHTTPService) sees c.MaxIdleConns < 0 and returns this wrapped error, e.g. ConnectionPoolConfig{MaxIdleConns: -5}.Validate().

Common situations: Environment-driven sizing producing negative numbers; negative values in YAML/JSON service config; arithmetic like maxConns - overhead underflowing to negative.

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


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/a3dff2272e064e85. Report an issue: GitHub.