kgretzky/evilginx2 · error

session ID not found: %d

Error message

session ID not found: %d

What it means

Returned by the by-ID session lookup (sessionsGetById path) when a buntdb transaction iterates the sessions_id index with AscendEqual for the given numeric id and no record matches. It means no Session with that integer Id exists in the database. The lookup found the index but zero entries equaled the pivot.

Source

Thrown at database/db_session.go:197

func (d *Database) sessionsDelete(id int) error {
	err := d.db.Update(func(tx *buntdb.Tx) error {
		_, err := tx.Delete(d.genIndex(SessionTable, id))
		return err
	})
	return err
}

func (d *Database) sessionsGetById(id int) (*Session, error) {
	s := &Session{}
	err := d.db.View(func(tx *buntdb.Tx) error {
		found := false
		err := tx.AscendEqual("sessions_id", d.getPivot(map[string]int{"id": id}), func(key, val string) bool {
			json.Unmarshal([]byte(val), s)
			found = true
			return false
		})
		if !found {
			return fmt.Errorf("session ID not found: %d", id)
		}
		return err
	})
	if err != nil {
		return nil, err
	}
	return s, nil
}

func (d *Database) sessionsGetBySid(sid string) (*Session, error) {
	s := &Session{}
	err := d.db.View(func(tx *buntdb.Tx) error {
		found := false
		err := tx.AscendEqual("sessions_sid", d.getPivot(map[string]string{"session_id": sid}), func(key, val string) bool {
			json.Unmarshal([]byte(val), s)
			found = true
			return false
		})

View on GitHub (pinned to 4c0988a1d9)

Solutions

  1. Verify the id exists by listing sessions (sessionsList) before fetching by id
  2. Prefer lookups by session_id string (GetSessionBySid) if that is the stable identifier in your flow
  3. Re-fetch the id from the current CreateSession result instead of reusing a cached one
  4. Handle the error as 'session expired/purged' and re-create or re-authenticate the session

Example fix

// before
s, err := db.GetSessionById(cachedID)
if err != nil { return err }
// after
s, err := db.GetSessionById(cachedID)
if err != nil {
    // session no longer exists; obtain a fresh one
    return handleExpiredSession(cachedID)
}
Defensive patterns

Strategy: try-catch

Validate before calling

sessions, err := db.GetSessions()
if err == nil {
    known := false
    for _, s := range sessions {
        if s.Id == wantedID { known = true; break }
    }
    if !known { return fmt.Errorf("id %d not present", wantedID) }
}

Type guard

func sessionExists(db *database.Database, id int) bool {
    _, err := db.GetSessionById(id)
    return err == nil
}

Try / catch

s, err := db.GetSessionById(id)
if err != nil {
    if strings.HasPrefix(err.Error(), "session ID not found") {
        return nil, ErrSessionExpired
    }
    return nil, err
}

Prevention

When it happens

Trigger: Calling GetSessionById (or anything that resolves a session by numeric Id, e.g. sessionsUpdate with a stale Id) with an id that was never created or was already deleted via session deletion/cleanup of expired sessions.

Common situations: A caller caches a Session.Id from a previous run and the database file was reset or the session was purged; passing a user-supplied numeric id that doesn't exist; off-by-one/derived ids (e.g. id from getNextId) used before creation completed.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of kgretzky/evilginx2@4c0988a1d9 (2026-09-05). Data as JSON: /api/errors/c71bc4d7cbfdccf0. Report an issue: GitHub.