kataras/iris · error
unknown value type of %T
Error message
unknown value type of %T
What it means
The Redis session database's decodeValue switches on the dynamic type returned from Redis: []byte (the common case) or string (from HGetAll). Any other type stored or returned cannot be decoded into the caller's out pointer, so it fails with this error reporting the unexpected Go type via %T.
Source
Thrown at sessions/sessiondb/redis/database.go:222
}
return nil
}
func (db *Database) decodeValue(val any, outPtr any) error {
if val == nil {
return nil
}
switch data := val.(type) {
case []byte:
// this is the most common type, as we save all values as []byte,
// the only exception is where the value is string on HGetAll command.
return sessions.DefaultTranscoder.Unmarshal(data, outPtr)
case string:
return sessions.DefaultTranscoder.Unmarshal([]byte(data), outPtr)
default:
return fmt.Errorf("unknown value type of %T", data)
}
}
func (db *Database) keys(fullSID string) []string {
keys, err := db.c.Driver.GetKeys(fullSID)
if err != nil {
db.logger.Debugf("unable to get all redis keys of session '%s': %v", fullSID, err)
return nil
}
return keys
}
// Visit loops through all session keys and values.
func (db *Database) Visit(sid string, cb func(key string, value any)) error {
kv, err := db.c.Driver.GetAll(db.makeSID(sid))
if err != nil {
return errView on GitHub (pinned to 7bedaf55a0)
Solutions
- Ensure session values are always written through the same Database/Transcoder so they are stored as []byte.
- Clear the affected Redis keys (FLUSHDB or targeted DEL) so stale/foreign values are removed.
- Inspect the offending key's Redis TYPE; if it's hash/list/etc. set by external code, migrate it to a plain string/[]byte.
- Use a compatible DefaultTranscoder on both the writing and reading sides.
Example fix
// before (external write)
redis-cli HSET sessions:sid key value
// after
sess.Set("key", "value") // library encodes as []byte internally Defensive patterns
Strategy: try-catch
Validate before calling
t, err := rdb.Type(ctx, "sessions:"+sid).Result()
if t != "string" {
return fmt.Errorf("session key has redis type %q; expected string", t)
} Type guard
func decodable(v any) bool {
switch v.(type) {
case []byte, string:
return true
}
return false
} Try / catch
if err := db.Decode(key, out); err != nil {
if strings.HasPrefix(err.Error(), "unknown value type of") {
// purge foreign-format key and re-create session
rdb.Del(ctx, key)
return newSession()
}
return err
} Prevention
- Write session values only through the library's Set/Update APIs, never raw redis-cli.
- Keep the same sessions transcoder across all services sharing the Redis DB.
- Flush or version-prefix session keys when upgrading serialization formats.
When it happens
Trigger: Decode/Visit on a Redis-backed session DB when the raw value stored in Redis is neither []byte nor string — typically after data was written by a different client/tool or a different session library version.
Common situations: Manually seeding Redis session keys with native Redis types (lists, hashes, ints via redis-cli), upgrading iris/sessions versions with old serialized values, or mixing transcoders between writers and readers.
Related errors
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/06149df0abd4dfc2.
Report an issue: GitHub.