juicedata/juicefs · error

failed to clean up sid %d

Error message

failed to clean up sid %d

What it means

When cleaning up a client session (by sid), redisMeta first removes the session's locks/ftype entries. If any of those sub-steps fails (it sets fail=true and logs e.g. 'SMembers %s: %s'), it aborts and returns this error instead of half-cleaning the session. The session record itself is left in place so the cleanup can be retried later.

Source

Thrown at pkg/meta/redis.go:2966

		fail = true
	}

	key = m.sustained(sid)
	if inodes, err := m.rdb.SMembers(ctx, key).Result(); err == nil {
		for _, sinode := range inodes {
			inode, _ := strconv.ParseUint(sinode, 10, 64)
			if err = m.doDeleteSustainedInode(sid, Ino(inode)); err != nil {
				logger.Warnf("Delete sustained inode %d of sid %d: %s", inode, sid, err)
				fail = true
			}
		}
	} else {
		logger.Warnf("SMembers %s: %s", key, err)
		fail = true
	}

	if fail {
		return fmt.Errorf("failed to clean up sid %d", sid)
	} else {
		var removed *redis.IntCmd
		if _, err := m.rdb.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
			pipe.HDel(ctx, m.sessionInfos(), ssid)
			removed = pipe.ZRem(ctx, m.allSessions(), ssid)
			m.genLog(ctx, pipe, time.Now(), "CLEANSESSION(%d)", sid)
			return nil
		}); err != nil {
			return err
		}
		if n, err := removed.Result(); err != nil {
			return err
		} else if n == 1 {
			return nil
		}
		return m.rdb.ZRem(ctx, legacySessions, ssid).Err()
	}
}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Read the preceding Warnf log line (e.g. 'SMembers ...: <err>') to find which sub-step failed and fix that Redis error.
  2. Retry the session cleanup once Redis is healthy; the operation is designed to be safe to re-run.
  3. If the session is truly dead and cleanup keeps failing, manually remove the session keys (sessionInfo hash entry and allSessions zset member) during a maintenance window.
  4. Check Redis ACLs allow reads/writes on the session-related keys.
Defensive patterns

Strategy: retry

Validate before calling

if err := rdb.Ping(ctx).Err(); err != nil { return err } // ensure redis is healthy before session GC

Try / catch

if err := cleanSession(ctx, sid); err != nil && strings.Contains(err.Error(), "failed to clean up sid") {
    logger.Warnf("session %d cleanup deferred, will retry", sid)
    scheduleRetry(sid, 5*time.Minute)
}

Prevention

When it happens

Trigger: Calling session cleanup (e.g. `juicefs status`/stale session GC path that ends in CLEANSESSION) when SMembers/HDEL on the session's lock or ftype keys fails, or the deliberately failing probe path detects a partial cleanup.

Common situations: Redis connection instability during session GC; removing a dead client's session while a replica failover is in progress; ACL restrictions preventing reads of session sub-keys.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/62afd7eba1f19237. Report an issue: GitHub.