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

  1. Ensure Database.Close() is called only after all session traffic has stopped (close it last in the shutdown sequence)
  2. Guard shutdown ordering: wait for in-flight requests to drain before closing the redis session DB
  3. 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

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.