crowdsecurity/crowdsec · warning
object not found
Error message
object not found
What it means
ItemNotFound is a sentinel error meaning the requested object does not exist in the database. It is returned when ent's IsNotFound(err) is true (e.g. GetAlertByID) and is mapped by the API layer (HandleDBErrors) to an HTTP 404 response.
Source
Thrown at pkg/database/errors.go:13
package database
import "errors"
var (
UserExists = errors.New("user already exist")
UserNotExists = errors.New("user doesn't exist")
HashError = errors.New("unable to hash")
InsertFail = errors.New("unable to insert row")
QueryFail = errors.New("unable to query")
UpdateFail = errors.New("unable to update")
DeleteFail = errors.New("unable to delete")
ItemNotFound = errors.New("object not found")
ParseTimeFail = errors.New("unable to parse time")
ParseDurationFail = errors.New("unable to parse duration")
MarshalFail = errors.New("unable to serialize")
BulkError = errors.New("unable to insert bulk")
ParseType = errors.New("unable to parse type")
InvalidIPOrRange = errors.New("invalid ip address / range")
InvalidFilter = errors.New("invalid filter")
)
View on GitHub (pinned to 909b515798)
Solutions
- Verify the ID exists (cscli alerts list / cscli decisions list) before fetching.
- Treat it as an expected 404: check errors.Is(err, database.ItemNotFound) and handle gracefully instead of retrying.
- If IDs come from another component, refresh them (IDs are not stable across DB resets).
- Check retention config — old alerts/decisions may have been purged.
Example fix
// before
alert, err := client.GetAlertByID(ctx, alertID)
if err != nil { return err }
// after
alert, err := client.GetAlertByID(ctx, alertID)
if errors.Is(err, database.ItemNotFound) {
log.Debugf("alert %d already gone", alertID)
return nil
} else if err != nil {
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// Go: confirm existence first when ID source is external _, err := client.GetAlertByID(ctx, alertID) exists := !errors.Is(err, database.ItemNotFound)
Type guard
func isNotFound(err error) bool { return errors.Is(err, database.ItemNotFound) } Try / catch
alert, err := client.GetAlertByID(ctx, alertID)
switch {
case errors.Is(err, database.ItemNotFound):
return nil // expected absence, not a failure
case err != nil:
return err
} Prevention
- Always check errors.Is(err, database.ItemNotFound) separately from generic errors
- Don't cache alert/decision IDs across DB resets or retention windows
- Account for retention-based purging when referencing old objects
When it happens
Trigger: GetAlertByID with an alert ID not in the DB; ExpireDecisionByID with an unknown decision ID; any database call whose error passes through HandleDBErrors after ent.IsNotFound matched.
Common situations: Querying an alert that was already deleted or expired by retention, using a decision ID received from a stale bouncer cache, race between reading a list and fetching a specific ID.
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
- no database configuration provided
- unable to update
- unable to delete
- unable to parse time
- unable to parse duration
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/84f94aca2d6e8f93.
Report an issue: GitHub.