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

  1. Verify the ID exists (cscli alerts list / cscli decisions list) before fetching.
  2. Treat it as an expected 404: check errors.Is(err, database.ItemNotFound) and handle gracefully instead of retrying.
  3. If IDs come from another component, refresh them (IDs are not stable across DB resets).
  4. 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

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


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/84f94aca2d6e8f93. Report an issue: GitHub.