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

  1. Always let the session manager generate sids (manager.SessionStart with an empty/absent cookie) — it uses crypto/rand with SessionIDPrefix and adequate length.
  2. If you generate sids yourself, use a long random value (crypto/rand, >=16 bytes hex) rather than derived-from-user values.
  3. On this error, regenerate a fresh sid and retry once instead of surfacing it to the user.
  4. 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

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


AI-assisted analysis of beego/beego@939cfde380 (2026-08-15). Data as JSON: /api/errors/c0291f3011fb6859. Report an issue: GitHub.