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
- Verify the id exists by listing sessions (sessionsList) before fetching by id
- Prefer lookups by session_id string (GetSessionBySid) if that is the stable identifier in your flow
- Re-fetch the id from the current CreateSession result instead of reusing a cached one
- 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
- Treat Session.Id as ephemeral; never persist it across restarts
- Resolve sessions by session_id string when possible
- Re-check existence after any delete/purge operation before further use
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
- session not found: %s
- session already exists: %s
- lure for path '%s' not found
- phishlet '%s' not found
- phishlet '%s' can't be deleted - you can only delete child p
AI-assisted analysis of kgretzky/evilginx2@4c0988a1d9 (2026-09-05).
Data as JSON: /api/errors/c71bc4d7cbfdccf0.
Report an issue: GitHub.