juicedata/juicefs · error
SMembers %s: %s
Error message
SMembers %s: %s
What it means
When fetching session detail (detail=true), getSession reads the set of sustained (held-open but not yet committed) chunk slices via SMembers on the session's `sustained` key. If Redis returns a non-Nil error for that read, it is wrapped and returned as `SMembers <sid>: <err>`. This is a Redis-level failure (connection, cluster downscaled, key type mismatch, NOAUTH, READONLY, etc.), not a data corruption issue.
Source
Thrown at pkg/meta/redis.go:552
}
func (m *redisMeta) getSession(sid string, detail bool) (*Session, error) {
ctx := Background()
info, err := m.rdb.HGet(ctx, m.sessionInfos(), sid).Bytes()
if err == redis.Nil { // legacy client has no info
info = []byte("{}")
} else if err != nil {
return nil, fmt.Errorf("HGet sessionInfos %s: %s", sid, err)
}
var s Session
if err := json.Unmarshal(info, &s); err != nil {
return nil, fmt.Errorf("corrupted session info; json error: %s", err)
}
s.Sid, _ = strconv.ParseUint(sid, 10, 64)
if detail {
inodes, err := m.rdb.SMembers(ctx, m.sustained(s.Sid)).Result()
if err != nil {
return nil, fmt.Errorf("SMembers %s: %s", sid, err)
}
s.Sustained = make([]Ino, 0, len(inodes))
for _, sinode := range inodes {
inode, _ := strconv.ParseUint(sinode, 10, 64)
s.Sustained = append(s.Sustained, Ino(inode))
}
locks, err := m.rdb.SMembers(ctx, m.lockedKey(s.Sid)).Result()
if err != nil {
return nil, fmt.Errorf("SMembers %s: %s", sid, err)
}
s.Flocks = make([]Flock, 0, len(locks)) // greedy
s.Plocks = make([]Plock, 0, len(locks))
for _, lock := range locks {
owners, err := m.rdb.HGetAll(ctx, lock).Result()
if err != nil {
return nil, fmt.Errorf("HGetAll %s: %s", lock, err)
}View on GitHub (pinned to c9a67b23e8)
Solutions
- Check Redis connectivity/auth from the client: run `redis-cli -u <meta-url> SMEMBERS <anykey>` and resolve NOAUTH/WRONGPASS/READONLY errors first.
- If cluster MOVED/resharding, point juicefs at the correct cluster endpoints or retry after resharding completes; ensure `juicefs` connects to the primary, not a replica.
- Verify no external process overwrote the `sustained*` keys with wrong types (TYPE check); fix or delete the wrongly typed key.
- If the session is stale/crashed, simply remove the session record instead of fetching details.
- Retry the status command on transient network errors; add --no-detail by listing without detail to skip SMembers entirely where supported.
Example fix
// before: status fails with SMembers <sid>: READONLY You can't write against a read only replica. // after: point the client at the primary endpoint // before juicefs status redis://replica-host:6379/1 --session 42 // after juicefs status redis://primary-host:6379/1 --session 42
Defensive patterns
Strategy: try-catch
Validate before calling
// Precheck Redis health and auth from the same endpoint used by juicefs $ redis-cli -u "$META_URL" PING $ redis-cli -u "$META_URL" SMEMBERS <prefix>sustained<sid>
Try / catch
sess, err := metaCli.GetSession(sid, true)
if err != nil {
var netErr net.Error
if errors.As(err, &netErr) || strings.Contains(err.Error(), "SMembers") {
// transient Redis failure: back off and retry
time.Sleep(2 * time.Second)
sess, err = metaCli.GetSession(sid, true)
}
if err != nil { return err }
} Prevention
- Point status/listing at the Redis primary, not a replica (READONLY errors).
- Keep credentials/ACLs consistent for all juicefs operations against the same volume.
- Avoid running status commands during cluster resharding or failover windows.
- Verify key types before manual Redis maintenance (TYPE check on sustained* keys).
- Retry once on transient network errors before reporting failure.
When it happens
Trigger: Calling `juicefs status <meta-url> --session <sid>` (GetSession/ListSessions with detail) while the Redis connection fails mid-request, the sustained key has been replaced with a non-set type, Redis is in READONLY replica mode, or auth/ACL denies access to the key.
Common situations: 1) Redis failover/timeout during the status command (MOVED, cluster resharding). 2) Wrong password/ACL after a config change (NOAUTH/WRONGPASS). 3) Querying a read-only replica or a proxy that rejects SMembers. 4) External tooling wrote a wrong-typed key at the sustained prefix.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- new session %d: %s
- HGet sessionInfos %s: %s
- new session: %s
- corrupted session info; json error: %s
- HGetAll %s: %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/65132c1d9b41100e.
Report an issue: GitHub.