crowdsecurity/crowdsec · error

while starting FlushAlerts scheduler: %w

Error message

while starting FlushAlerts scheduler: %w

What it means

StartFlushScheduler registers a gocron job that runs FlushAlerts every minute to prune old alerts. This error wraps a failure returned by scheduler.NewJob when the job could not be registered (e.g. invalid scheduling parameters), and it aborts scheduler startup.

Source

Thrown at pkg/database/flush.go:64

		maxItems = *config.MaxItems
	}

	// Init & Start cronjob every minute for alerts
	scheduler, err := gocron.NewScheduler(
		gocron.WithLocation(time.UTC),
		gocron.WithLogger(logging.GoCronLoggerAdapter{Logger: c.Log}),
	)
	if err != nil {
		return nil, err
	}

	_, err = scheduler.NewJob(
		gocron.DurationJob(1*time.Minute),
		gocron.NewTask(c.FlushAlerts, ctx, time.Duration(config.MaxAge), maxItems),
		gocron.WithSingletonMode(gocron.LimitModeReschedule),
	)
	if err != nil {
		return nil, fmt.Errorf("while starting FlushAlerts scheduler: %w", err)
	}

	// Init & Start cronjob every hour for bouncers/agents
	if config.AgentsGC != nil {
		if config.AgentsGC.Cert != nil {
			duration, err := cstime.ParseDurationWithDays(*config.AgentsGC.Cert)
			if err != nil {
				return nil, fmt.Errorf("while parsing agents cert auto-delete duration: %w", err)
			}

			config.AgentsGC.CertDuration = &duration
		}

		if config.AgentsGC.LoginPassword != nil {
			duration, err := cstime.ParseDurationWithDays(*config.AgentsGC.LoginPassword)
			if err != nil {
				return nil, fmt.Errorf("while parsing agents login/password auto-delete duration: %w", err)
			}

View on GitHub (pinned to 909b515798)

Solutions

  1. Ensure the database Client (*c) passed to StartFlushScheduler is fully initialized and non-nil before creating the scheduler job.
  2. Check that gocron.NewScheduler succeeded (its error is checked just before) and that the scheduler is not already stopped.
  3. Inspect the wrapped error (%w) for the concrete gocron cause — e.g. invalid job parameters — and fix that input.
  4. If running a custom build, verify gocron v2 options (DurationJob, NewTask, SingletonMode) are constructed exactly as in the source.

Example fix

// before
c, _ := database.NewClient(cfg) // error ignored, c may be nil
scheduler, err := c.StartFlushScheduler(ctx, flushCfg)

// after
c, err := database.NewClient(cfg)
if err != nil {
    return err
}
scheduler, err := c.StartFlushScheduler(ctx, flushCfg)
Defensive patterns

Strategy: try-catch

Validate before calling

if c == nil {
    return errors.New("database client must be initialized before StartFlushScheduler")
}
if config == nil {
    return errors.New("flush config must not be nil")
}

Type guard

if c == nil || c.Ent == nil {
    return errors.New("database client not initialized")
}

Try / catch

scheduler, err := c.StartFlushScheduler(ctx, flushCfg)
if err != nil {
    if errors.Is(err, gocron.ErrUpdateJobFuncNotSet) || strings.Contains(err.Error(), "while starting FlushAlerts scheduler") {
        // handle scheduler init failure
    }
    return err
}

Prevention

When it happens

Trigger: scheduler.NewJob returns an error when registering the FlushAlerts task — typically because the scheduler rejects the job definition (nil task function receiver, invalid duration/job options, or scheduler already shut down).

Common situations: Calling StartFlushScheduler with a nil or zero-value database Client (c is nil, so gocron.NewTask builds a task it cannot schedule); reusing a scheduler that has been stopped; corrupted gocron options combination.

Related errors


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