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

  1. 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.
  2. Use cmd.Result() on the correct typed command (e.g. StringCmd for GET, SliceCmd for arrays) instead of forcing Int().
  3. If a status string may be non-numeric ('OK', 'PONG'), handle it explicitly before calling Int().
  4. 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

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


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