crowdsecurity/crowdsec · error

controller init: %w

Error message

controller init: %w

What it means

InitController wraps controller.Init(), which registers all LAPI routes and middlewares on the gin router (and may run DB auto-migrations). A failure here means the API surface could not be built — commonly a database error during route/controller setup.

Source

Thrown at pkg/apiserver/apiserver.go:548

			return errors.New("plugins are enabled, but config_paths.plugin_dir is not defined")
		}

		err := pluginBroker.Init(ctx, cConfig.PluginConfig, s.cfg.Profiles, cConfig.ConfigPaths)
		if err != nil {
			return fmt.Errorf("plugin broker: %w", err)
		}

		log.Info("initiated plugin broker")
		s.AttachPluginBroker(pluginBroker)
	}

	return nil
}

func (s *APIServer) InitController() error {
	err := s.controller.Init()
	if err != nil {
		return fmt.Errorf("controller init: %w", err)
	}

	if s.cfg.TLS == nil {
		return nil
	}

	// TLS is configured: create the TLSAuth middleware for agents and bouncers

	cacheExpiration := time.Hour
	if s.cfg.TLS.CacheExpiration != nil {
		cacheExpiration = *s.cfg.TLS.CacheExpiration
	}

	s.controller.HandlerV1.Middlewares.JWT.TlsAuth, err = v1.NewTLSAuth(s.cfg.TLS.AllowedAgentsOU, s.cfg.TLS.CRLPath,
		cacheExpiration,
		log.WithFields(log.Fields{
			"component": "tls-auth",
			"type":      "agent",

View on GitHub (pinned to 909b515798)

Solutions

  1. Read the wrapped cause — it identifies whether DB, profiles, or routes failed.
  2. Verify DB connectivity: `cscli lapi status` or `cscli alerts list`.
  3. Validate profiles.yaml syntax and referenced filters.
  4. Check DB server version compatibility with the crowdsec driver.
Defensive patterns

Strategy: retry

Validate before calling

// before InitController, verify DB session is alive
if err := server.PingDB(ctx); err != nil { // or cscli lapi status
    return fmt.Errorf("DB not ready: %w", err)
}

Try / catch

if err := server.InitController(); err != nil {
    if strings.Contains(err.Error(), "controller init") && isDBError(err) {
        // wait and retry once the DB is back
        time.Sleep(5 * time.Second)
        return server.InitController()
    }
    return err
}

Prevention

When it happens

Trigger: InitController called after NewServer when the underlying controller.Init fails: DB session errors (e.g. MySQL/Postgres gone after startup), failure loading profiles, or middleware init problems.

Common situations: DB dropped/restarted between NewServer and InitController; bad profiles.yaml; driver/migration issues with an unsupported DB version.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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