beego/beego · error
newsid %s exist
Error message
newsid %s exist
What it means
The file-based session provider stores each session as savePath/<sid[0]>/<sid[1]>/<sid>. SessionRegenerate(oldsid, sid) must create a brand-new file for the new session id; if a file for the new sid already exists on disk, it refuses to overwrite it. This is a new-session-id collision with data already on disk.
Source
Thrown at server/web/session/sess_file.go:254
}
return a.total
}
// SessionRegenerate Generate new sid for file session.
// it deletes old file and create new file named from new sid.
func (fp *FileProvider) SessionRegenerate(ctx context.Context, oldsid, sid string) (Store, error) {
filepder.lock.Lock()
defer filepder.lock.Unlock()
oldPath := filepath.Join(fp.savePath, string(oldsid[0]), string(oldsid[1]))
oldSidFile := filepath.Join(oldPath, oldsid)
newPath := filepath.Join(fp.savePath, string(sid[0]), string(sid[1]))
newSidFile := filepath.Join(newPath, sid)
// new sid file is exist
_, err := os.Stat(newSidFile)
if err == nil {
return nil, fmt.Errorf("newsid %s exist", newSidFile)
}
err = os.MkdirAll(newPath, 0o755)
if err != nil {
SLogger.Println(err.Error())
}
// if old sid file exist
// 1.read and parse file content
// 2.write content to new sid file
// 3.remove old sid file, change new sid file atime and ctime
// 4.return FileSessionStore
_, err = os.Stat(oldSidFile)
if err == nil {
b, err := os.ReadFile(oldSidFile)
if err != nil {
return nil, err
}View on GitHub (pinned to 939cfde380)
Solutions
- Always let the session manager generate sids (manager.SessionStart with an empty/absent cookie) — it uses crypto/rand with SessionIDPrefix and adequate length.
- If you generate sids yourself, use a long random value (crypto/rand, >=16 bytes hex) rather than derived-from-user values.
- On this error, regenerate a fresh sid and retry once instead of surfacing it to the user.
- Clean stale session files in savePath between test runs / environments.
Example fix
// before (deterministic sid -> collides on rerun)
sess, err := sm.SessionRegenerate(ctx, oldsid, "user-1234-sid")
// after
newsid, _ := sm.SessionID() // or accept the manager-generated id
// if newsid already taken, loop:
for {
if _, err = sm.SessionRegenerate(ctx, oldsid, newsid); err == nil { break }
newsid, _ = sm.SessionID()
} Defensive patterns
Strategy: retry
Validate before calling
// if you generate sids yourself, verify the target file is free before regenerating
func sidFileFree(savePath, sid string) bool {
p := filepath.Join(savePath, sid[:1], sid[1:2], sid)
_, err := os.Stat(p)
return os.IsNotExist(err)
} Try / catch
for attempt := 0; attempt < 3; attempt++ {
store, err := mgr.SessionRegenerate(ctx, oldsid, newSid)
if err == nil { return store, nil }
if !strings.Contains(err.Error(), "exist") { return nil, err }
newSid = mustRandomSid() // collision: try a fresh random id
} Prevention
- Let the manager generate session ids; never derive them from user data or timestamps.
- Keep SessionIDLength at default/16+ bytes of entropy.
- Purge savePath between test runs and isolate savePath per environment.
When it happens
Trigger: Passing a fixed/app-supplied sid that was issued before (e.g. reusing a client cookie after logout+delete-less runs); SessionIDLength configured very short making random sids collide; two concurrent requests regenerating to the same sid; stale session files left in savePath across test reruns that inject deterministic sids.
Common situations: Test suites with hardcoded session ids re-run against the same savePath; custom sid generation (timestamp- or user-id-based) instead of the manager's random sessionID(); short SessionIDLength in ManagerConfig; shared savePath between environments.
Related errors
- the target config file: %s don't exist
- session: unknown provide %q (forgotten import?)
- Could not successfully read from the system CSPRNG
- session: Register provide is nil
- unsupported operation
AI-assisted analysis of beego/beego@939cfde380 (2026-08-15).
Data as JSON: /api/errors/c0291f3011fb6859.
Report an issue: GitHub.