juicedata/juicefs · error
corrupted session info; json error: %s
Error message
corrupted session info; json error: %s
What it means
Thrown by dbMeta.getSession when the session's serialized `info` JSON column cannot be unmarshalled into a Session. The info column holds client metadata (hostname, IPs, process, mountpoint) written as JSON at session creation; if it is corrupt or not valid JSON matching the Session schema, GetSession/FindSession fails for that session.
Source
Thrown at pkg/meta/sql.go:839
var s Session
var info []byte
switch row := row.(type) {
case *session2:
s.Sid = row.Sid
s.Expire = time.Unix(row.Expire, 0)
info = row.Info
case *session:
s.Sid = row.Sid
s.Expire = time.Unix(row.Heartbeat, 0).Add(time.Minute * 5)
info = row.Info
if info == nil { // legacy client has no info
info = []byte("{}")
}
default:
return nil, fmt.Errorf("invalid type: %T", row)
}
if err := json.Unmarshal(info, &s); err != nil {
return nil, fmt.Errorf("corrupted session info; json error: %s", err)
}
if detail {
var (
srows []sustained
frows []flock
prows []plock
)
err := m.roTxn(Background(), func(ses *xorm.Session) error {
if err := ses.Find(&srows, &sustained{Sid: s.Sid}); err != nil {
return fmt.Errorf("find sustained %d: %s", s.Sid, err)
}
s.Sustained = make([]Ino, 0, len(srows))
for _, srow := range srows {
s.Sustained = append(s.Sustained, srow.Inode)
}
if err := ses.Find(&frows, &flock{Sid: s.Sid}); err != nil {
return fmt.Errorf("find flock %d: %s", s.Sid, err)View on GitHub (pinned to c9a67b23e8)
Solutions
- Check the offending row: `SELECT sid, info FROM jfs_session2 WHERE sid=<id>` and fix or delete it if it is stale.
- If the session is dead, run `juicefs gc --delete` or wait for stale-session cleanup (doCleanStaleSession) to remove the row.
- If rows were corrupted by a restore, re-run session info writers by remounting clients.
- For SQLite, run integrity_check; for MySQL, check table corruption and repair.
Example fix
// before: SELECT info shows truncated JSON: '{"ip":["10.0.0', unmarshal fails
// after: remove stale/corrupt row, then re-query
DELETE FROM jfs_session2 WHERE sid = 42;
juicefs status sqlite3://test.db Defensive patterns
Strategy: validation
Validate before calling
// pre-validate a session's info JSON before inspecting status output
var probe map[string]interface{}
if err := json.Unmarshal(info, &probe); err != nil {
log.Printf("session info corrupt, treat session as stale: %v", err)
} Type guard
func validSessionInfo(info []byte) bool {
var s map[string]interface{}
return json.Unmarshal(info, &s) == nil
} Try / catch
s, err := m.GetSession(sid, false)
if err != nil && strings.Contains(err.Error(), "corrupted session info") {
logger.Warnf("skipping corrupt session %d: %v", sid, err) // treat as stale, allow cleanup
return nil
} Prevention
- Never hand-edit the session table's info column.
- Restore DB backups quiesced (no active writers) to avoid torn JSON rows.
- Periodically run `juicefs status` and investigate sessions that fail to render.
When it happens
Trigger: `juicefs status <meta-url>` or `juicefs info` listing sessions where a row's info column was truncated, manually edited, written by a client with a legacy nil-info column containing garbage, or corrupted by a DB incident/partial backup restore.
Common situations: Restoring a database backup mid-write; manual DB surgery on the session table; very old clients (pre-info schema) combined with corrupted rows; disk-level corruption on self-hosted MySQL/SQLite.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- json: %s
- corrupted session info; json error: %s
- The entry of the root inode was not found
- new session: %s
- unknown message type %d
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/c79350fa5f57a5e2.
Report an issue: GitHub.