redis/go-redis · error

redis: invalid database number: %w

Error message

redis: invalid database number: %w

What it means

In setupFailoverConnParams, the "db" query parameter of a failover URL must parse as an integer. If strconv.Atoi fails, the error is wrapped with %w and returned as this message — the underlying strconv error (e.g. strconv.Atoi: parsing "abc": invalid syntax) is preserved for errors.As/Is inspection.

Source

Thrown at sentinel.go:512

	o.PipelineWriteBufferSize = q.int("pipeline_write_buffer_size")
	o.ConnMaxLifetime = q.duration("conn_max_lifetime")
	if q.has("conn_max_lifetime_jitter") {
		o.ConnMaxLifetimeJitter = min(q.duration("conn_max_lifetime_jitter"), o.ConnMaxLifetime)
	}
	o.ConnMaxIdleTime = q.duration("conn_max_idle_time")
	o.PoolTimeout = q.duration("pool_timeout")
	o.DisableIdentity = q.bool("disableIdentity")
	o.IdentitySuffix = q.string("identitySuffix")
	o.UnstableResp3 = q.bool("unstable_resp3")

	if q.err != nil {
		return nil, q.err
	}

	if tmp := q.string("db"); tmp != "" {
		db, err := strconv.Atoi(tmp)
		if err != nil {
			return nil, fmt.Errorf("redis: invalid database number: %w", err)
		}
		o.DB = db
	}

	addrs := q.strings("addr")
	for _, addr := range addrs {
		h, p, err := net.SplitHostPort(addr)
		if err != nil || h == "" || p == "" {
			return nil, fmt.Errorf("redis: unable to parse addr param: %s", addr)
		}

		o.SentinelAddrs = append(o.SentinelAddrs, net.JoinHostPort(h, p))
	}

	if o.TLSConfig != nil && q.has("skip_verify") {
		o.TLSConfig.InsecureSkipVerify = q.bool("skip_verify")
	}

View on GitHub (pinned to c5cad058c7)

Solutions

  1. Fix the db query parameter to be a plain integer: redis://host:26379?db=2
  2. Check the environment variable interpolation that builds the URL and verify the resolved value
  3. Inspect the wrapped strconv error via errors.As to see the exact offending value

Example fix

// before
url := fmt.Sprintf("redis://host:26379?db=%s", os.Getenv("REDIS_DB")) // REDIS_DB="abc"
// after
url := fmt.Sprintf("redis://host:26379?db=%s", os.Getenv("REDIS_DB")) // REDIS_DB="2"
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(raw)
if err != nil { return err }
db := u.Query().Get("db")
if db != "" {
    if _, err := strconv.Atoi(db); err != nil { return fmt.Errorf("db param %q is not an integer", db) }
}

Try / catch

var serr *strconv.NumError
opt, err := redis.ParseFailoverURL(raw)
if err != nil && errors.As(err, &serr) { return fmt.Errorf("bad numeric param %q", serr.Num) }

Prevention

When it happens

Trigger: ParseFailoverURL with ?db=abc or ?db=1.5 in the query string.

Common situations: Putting a database name instead of an index in the query, environment-variable substitution failing so a placeholder like ${DB} leaks into the URL, or copy-paste leaving stray characters in the query.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01). Data as JSON: /api/errors/d743fd174698c4c7. Report an issue: GitHub.