{"record":{"id":"2643a6bdece04a25","repo":"juicedata/juicefs","slug":"get-session-id-s-2643a6","errorCode":null,"errorMessage":"get session ID: %s","messagePattern":"get session ID: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/sql.go","lineNumber":810,"sourceCode":"\t\t\t})\n\t\t} else {\n\t\t\tif err = m.txn(func(s *xorm.Session) error {\n\t\t\t\tif err := mustInsert(s, &beans); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tm.genLog(Background(), s, time.Now().UnixNano(), \"NEWSESSION(%d,%d,%s)\", m.sid, beans.Expire, logEncode(sinfo))\n\t\t\t\treturn nil\n\t\t\t}); err == nil {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif isDuplicateEntryErr(err) {\n\t\t\t\tlogger.Warnf(\"session id %d is already used\", m.sid)\n\t\t\t\tif v, e := m.incrCounter(\"nextSession\", 1); e == nil {\n\t\t\t\t\tm.sid = uint64(v)\n\t\t\t\t\tcontinue\n\t\t\t\t} else {\n\t\t\t\t\treturn fmt.Errorf(\"get session ID: %s\", e)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn fmt.Errorf(\"insert new session %d: %s\", m.sid, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (m *dbMeta) getSession(row interface{}, detail bool) (*Session, error) {\n\tvar s Session\n\tvar info []byte\n\tswitch row := row.(type) {\n\tcase *session2:\n\t\ts.Sid = row.Sid\n\t\ts.Expire = time.Unix(row.Expire, 0)\n\t\tinfo = row.Info\n\tcase *session:","sourceCodeStart":792,"sourceCodeEnd":828,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/sql.go#L792-L828","documentation":"When inserting a new session row, a duplicate primary key on the session ID triggers re-allocation via the nextSession counter. If that incrCounter call itself fails, the error is wrapped as 'get session ID: %s' and session creation fails, preventing the mount.","triggerScenarios":"Mount with SQL metadata when the generated session ID collides (isDuplicateEntryErr) and the subsequent incrCounter('nextSession', 1) transaction fails — DB connection error, deadlock, or permission failure on the counter row.","commonSituations":"Restored/copied metadata databases with stale counter values causing repeated SID collisions; transient DB failures exactly during collision retry; counter row deleted or corrupted.","solutions":["Retry the mount — the collision retry usually succeeds once the counter increments","Verify the nextSession counter row exists and is correct (SELECT ... WHERE name='nextSession')","Check DB connectivity and error logs for the wrapped incrCounter failure","If collisions persist after a restored DB, manually fix the nextSession counter above the max session ID"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Verify counter sanity after restoring a metadata DB\nSELECT MAX(sid) FROM session2; SELECT value FROM setting WHERE name='nextSession';","typeGuard":null,"tryCatchPattern":"err := mountWithRetry(sqlURL, 3) // transient incrCounter failures usually clear on retry","preventionTips":["Fix nextSession counter after metadata restore (set above MAX(sid))","Monitor DB health before mounts","Retry transient DB failures automatically"],"tags":["database","sql","session","counter","duplicate-key"],"backgroundTag":"database-query-failed","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}