redis/go-redis · error
redis: can't parse int reply: %.100q
Error message
redis: can't parse int reply: %.100q
What it means
ReadInt expects the reply line to be one of the numeric-ish reply types: RESP3 integer, status string, or bulk string containing a decimal integer. If the first byte of the reply line is any other type marker (e.g. an array, map, float, nil, or error framing that isn't a RedisError), the parser cannot convert it and returns 'redis: can't parse int reply: <line prefix>'. This is a reply-type mismatch: the command sent does not match what the caller is trying to decode.
Source
Thrown at internal/proto/reader.go:516
case RespInt, RespStatus:
return util.ParseInt(line[1:], 10, 64)
case RespString:
s, err := r.readStringReply(line)
if err != nil {
return 0, err
}
return strconv.ParseInt(s, 10, 64)
case RespBigInt:
b, err := r.readBigInt(line)
if err != nil {
return 0, err
}
if !b.IsInt64() {
return 0, fmt.Errorf("bigInt(%s) value out of range", b.String())
}
return b.Int64(), nil
}
return 0, fmt.Errorf("redis: can't parse int reply: %.100q", line)
}
func (r *Reader) ReadUint() (uint64, error) {
line, err := r.ReadLine()
if err != nil {
return 0, err
}
switch line[0] {
case RespInt, RespStatus:
return util.ParseUint(line[1:], 10, 64)
case RespString:
s, err := r.readStringReply(line)
if err != nil {
return 0, err
}
return strconv.ParseUint(s, 10, 64)
case RespBigInt:
b, err := r.readBigInt(line)View on GitHub (pinned to c5cad058c7)
Solutions
- Log the command and its raw reply type first (cmd.String() / redis.NewStringResult) to see the actual shape, then pick the matching accessor: .Text() for strings, .Int() only for numeric replies.
- Use cmd.Result() on the correct typed command (e.g. StringCmd for GET, SliceCmd for arrays) instead of forcing Int().
- If a status string may be non-numeric ('OK', 'PONG'), handle it explicitly before calling Int().
- Verify the server/proxy isn't rewriting reply types; compare reply shapes with redis-cli --resp (RESP3) directly against the same endpoint.
Example fix
// before: assumes numeric reply
n, err := client.Do(ctx, "GET", key).Int64()
// after: handle string reply explicitly
v, err := client.Do(ctx, "GET", key).Result()
if err != nil { return err }
s, ok := v.(string)
if !ok { return fmt.Errorf("unexpected reply type %T", v) }
n, err := strconv.ParseInt(s, 10, 64) Defensive patterns
Strategy: type-guard
Validate before calling
// Before forcing an int conversion, inspect the raw reply type:
// prefer the typed command classes (StringCmd, IntCmd, SliceCmd) over raw Do().
func replyIsNumeric(v interface{}) bool {
switch v.(type) {
case int64, string:
return true
}
return false
} Type guard
func asInt64(v interface{}) (int64, bool) {
switch t := v.(type) {
case int64:
return t, true
case string:
n, err := strconv.ParseInt(t, 10, 64)
return n, err == nil
}
return 0, false
} Try / catch
n, err := client.Do(ctx, "GET", key).Int64()
if err != nil {
if strings.HasPrefix(err.Error(), "redis: can't parse int reply:") {
return fmt.Errorf("reply shape mismatch for GET %s — check command/endpoint: %w", key, err)
}
return err
} Prevention
- Always use the typed command API (Get -> StringCmd, Incr -> IntCmd) instead of raw Do()+Int().
- Match the accessor to the known reply type of the command; when unsure, log cmd.String() first.
- Re-check reply shapes after server upgrades — some commands changed return types across Redis versions.
- Validate Lua script return types in CI by calling them against a real Redis in tests.
When it happens
Trigger: Calling .Int()/.Int64() on a command whose reply isn't an integer — e.g. calling Int() on GET that returned a string 'abc', calling Int() on a command that returned an array/map/float/bool, or routing a command to the wrong endpoint so the reply type differs from expectation (via readReply, readXMessage, readStreamGroups, readXInfoStreamGroupPending, readXInfoStreamConsumers, readEngines). Also triggered when a status reply contains non-numeric text (e.g. 'OK' or 'PONG') and the code expects an int.
Common situations: Misusing a generic Do()/NewCommand result by calling .Int() without knowing the reply shape; a Lua script whose return type changed (e.g. returning a table instead of a number); server version differences where a command returns a float (Redis 6.2+ INCRBYFLOAT-like paths) but the code parses Int; proxy or cluster middleware that rewrites replies into different types.
Related errors
- redis: function stats unexpected running_script key %s
- redis: function stats unexpected %s engine map length
- redis: unexpected key %q in CLUSTER LINKS reply
- redis: VectorScoreSliceCmd expects even number of elements,
- redis: got %d elements in the VLINKS array, wanted a multipl
AI-assisted analysis of redis/go-redis@c5cad058c7 (2026-09-01).
Data as JSON: /api/errors/81bcd4a5aa6afcd6.
Report an issue: GitHub.