redis/go-redis · error

redis.Scan(unsupported %s)

Error message

redis.Scan(unsupported %s)

What it means

When decoding a Redis hash value into a struct field, hscan assigns a decoder per field type. Fields whose Go type has no registered decoder (e.g. nested structs, maps, bool arrays, complex numbers) get decodeUnsupported, which returns 'redis.Scan(unsupported <type>)'. The field is left untouched.

Source

Thrown at internal/hscan/hscan.go:206

	f.SetFloat(v)
	return nil
}

func decodeString(f reflect.Value, s string) error {
	f.SetString(s)
	return nil
}

func decodeSlice(f reflect.Value, s string) error {
	// []byte slice ([]uint8).
	if f.Type().Elem().Kind() == reflect.Uint8 {
		f.SetBytes([]byte(s))
	}
	return nil
}

func decodeUnsupported(v reflect.Value, s string) error {
	return fmt.Errorf("redis.Scan(unsupported %s)", v.Type())
}

View on GitHub (pinned to c5cad058c7)

Solutions

  1. Change the field type to a supported one (string, numeric, []byte, bool, time.Duration, slice of these)
  2. Store JSON in a string field and json.Unmarshal it separately after Scan
  3. Register a custom decoder if the library's extension point allows it
  4. Flatten nested structs into simple fields

Example fix

// before
type Config struct {
	Meta map[string]string `redis:"meta"` // unsupported
}
// after
type Config struct {
	Meta string `redis:"meta"` // raw JSON string
}
cfg := Config{}
redis.Scan(&cfg)
json.Unmarshal([]byte(cfg.Meta), &metaMap)
Defensive patterns

Strategy: validation

Validate before calling

func onlySupportedFields(v interface{}) error {
	t := reflect.TypeOf(v)
	if t.Kind() != reflect.Ptr {
		return nil
	}
	t = t.Elem()
	for i := 0; i < t.NumField(); i++ {
		k := t.Field(i).Type.Kind()
		switch k {
		case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
			reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
			reflect.Float32, reflect.Float64, reflect.Bool, reflect.Slice:
		default:
			return fmt.Errorf("field %s has unsupported kind %s", t.Field(i).Name, k)
		}
	}
	return nil
}

Try / catch

if err := redis.Scan(&cfg); err != nil {
	if strings.Contains(err.Error(), "unsupported") {
		log.Printf("struct has unsupported field type: %v", err)
	}
}

Prevention

When it happens

Trigger: Scanning an HGETALL result into a struct containing a field of an unsupported kind — e.g. a nested struct, a map, a time.Time without an appropriate hook, a slice of non-bytes, or a pointer field.

Common situations: Struct fields for JSON blobs stored as Redis strings (need manual unmarshal); nested objects; custom types without a registered codec.

Related errors


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