caddyserver/caddy · error

loading event subscriber modules: %v

Error message

loading event subscriber modules: %v

What it means

The events app's Provision loads each subscription's HandlersRaw via ctx.LoadModule; any failure in resolving, provisioning, or validating an event handler module (modules under caddy.events.handlers.*) is wrapped with this message.

Source

Thrown at modules/caddyevents/app.go:130

func (App) CaddyModule() caddy.ModuleInfo {
	return caddy.ModuleInfo{
		ID:  "events",
		New: func() caddy.Module { return new(App) },
	}
}

// Provision sets up the app.
func (app *App) Provision(ctx caddy.Context) error {
	app.logger = ctx.Logger()
	app.subscriptions = make(map[string]map[caddy.ModuleID][]Handler)

	for _, sub := range app.Subscriptions {
		if sub.HandlersRaw == nil {
			continue
		}
		handlersIface, err := ctx.LoadModule(sub, "HandlersRaw")
		if err != nil {
			return fmt.Errorf("loading event subscriber modules: %v", err)
		}
		for _, h := range handlersIface.([]any) {
			sub.Handlers = append(sub.Handlers, h.(Handler))
		}
		if len(sub.Handlers) == 0 {
			// pointless to bind without any handlers
			return fmt.Errorf("no handlers defined")
		}
	}

	return nil
}

// Start runs the app.
func (app *App) Start() error {
	for _, sub := range app.Subscriptions {
		if err := app.Subscribe(sub); err != nil {
			return err

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Read the wrapped error to distinguish 'module not registered' from handler-level provisioning failures.
  2. Fix or rebuild: include the plugin via xcaddy, or correct the handler name/config.
  3. Run 'caddy list-modules | grep caddy.events' to see available event handler modules in your binary.
  4. Validate with 'caddy validate --config ...' before deploying.

Example fix

// before (caddyfile)
{
    events {
        on tls cert_obtained {
            handler nonexistent
        }
    }
}

// after (use a handler that exists in your build, or remove the block)
{
    events {
        on tls cert_obtained {
            handler exec {
                command echo obtained
            }
        }
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// before load, confirm every referenced event handler module exists
for _, id := range eventHandlerModuleIDs(cfg) {
    if _, err := caddy.GetModule(id); err != nil {
        return fmt.Errorf("event handler %s not in build: %w", id, err)
    }
}

Try / catch

if err := caddy.Validate(cfg); err != nil {
    if strings.Contains(err.Error(), "loading event subscriber modules") {
        // nested cause identifies the handler; fix module id or rebuild
    }
    return err
}

Prevention

When it happens

Trigger: An events subscription with handlers whose module name is not registered (e.g. a third-party event handler not built in) or whose inline config fails its own provisioning.

Common situations: xcaddy builds missing the events plugin; typos in the handler module name; JSON event configs with wrong inline keys; plugin API changes across Caddy versions breaking the handler's Provision.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/2e9824269602f1d1. Report an issue: GitHub.