kataras/iris · error
redis: already closed
Error message
redis: already closed
What it means
ErrRedisClosed is a sentinel error ('redis: already closed') returned when a redis session database operation is attempted after the redis driver connection has already been terminated via Database.Close(). The underlying redis client refuses to run commands on a closed connection. It signals a lifecycle bug in the caller, not a redis server problem.
Source
Thrown at sessions/sessiondb/redis/database.go:309
if err != nil {
db.logger.Debugf("Database.Release.Driver.Delete: %s: %v", sid, err)
}
return err
}
// Close terminates the redis connection.
func (db *Database) Close() error {
return closeDB(db)
}
func closeDB(db *Database) error {
return db.c.Driver.CloseConnection()
}
var (
// ErrRedisClosed an error with message 'redis: already closed'
ErrRedisClosed = errors.New("redis: already closed")
// ErrKeyNotFound a type of error of non-existing redis keys.
// The producers(the library) of this error will dynamically wrap this error(fmt.Errorf) with the key name.
// Usage:
// if err != nil && errors.Is(err, ErrKeyNotFound) {
// [...]
// }
ErrKeyNotFound = errors.New("key not found")
)
View on GitHub (pinned to 7bedaf55a0)
Solutions
- Ensure Database.Close() is called only after all session traffic has stopped (close it last in the shutdown sequence)
- Guard shutdown ordering: wait for in-flight requests to drain before closing the redis session DB
- Remove duplicate Close calls (e.g. both defer Close and explicit Close)
Example fix
// before db.Close() go session.Update(sid, values) // after session.Update(sid, values) db.Close()
Defensive patterns
Strategy: type-guard
Validate before calling
if db.IsClosed() { return errors.New("session store closed") }
_ = db.Ping() // pre-check connectivity Type guard
func isRedisClosedErr(err error) bool { return errors.Is(err, redisdb.ErrRedisClosed) } Try / catch
if err := db.Update(sid, values); err != nil {
if errors.Is(err, redisdb.ErrRedisClosed) {
// skip/queue: store shut down
return nil
}
return err
} Prevention
- Close the session database last in shutdown, after draining in-flight requests
- Never call Close twice; track closed state once
- Use defer Close only at the very top-level owner of the connection
When it happens
Trigger: Calling Acquire/Update/Release/other Database methods after calling Database.Close(); closing the sessiondb (e.g. on app shutdown) while a background goroutine or in-flight request still touches the session store.
Common situations: Graceful shutdown handlers that close redis before all workers finish; double-Close in defer chains; using a session Database across application restarts where it was closed during teardown.
Related errors
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/c894d3ac2b419f7f.
Report an issue: GitHub.