caddyserver/caddy · error

loading log core module: %v

Error message

loading log core module: %v

What it means

Thrown when ctx.LoadModule fails to load the zapcore.Core module configured under the core key of a log config (CoreRaw). The loaded module is tee'd onto the log's default core, so a bad core module aborts provisioning of the whole logs app.

Source

Thrown at logging.go:388

		cl.encoder = mod.(zapcore.Encoder)

		// if the encoder module needs the writer to determine
		// the correct default to use for a nested encoder, we
		// pass it down as a secondary provisioning step
		if cfd, ok := mod.(ConfiguresFormatterDefault); ok {
			if err := cfd.ConfigureDefaultFormat(cl.writerOpener); err != nil {
				return fmt.Errorf("configuring default format for encoder module: %v", err)
			}
		}
	}
	if cl.encoder == nil {
		cl.encoder = newDefaultProductionLogEncoder(cl.writerOpener)
	}
	cl.buildCore()
	if cl.CoreRaw != nil {
		mod, err := ctx.LoadModule(cl, "CoreRaw")
		if err != nil {
			return fmt.Errorf("loading log core module: %v", err)
		}
		core := mod.(zapcore.Core)
		cl.core = zapcore.NewTee(cl.core, core)
	}
	return nil
}

func (cl *BaseLog) buildCore() {
	// logs which only discard their output don't need
	// to perform encoding or any other processing steps
	// at all, so just shortcut to a nop core instead
	if _, ok := cl.writerOpener.(*DiscardWriter); ok {
		cl.core = zapcore.NewNopCore()
		return
	}
	c := zapcore.NewCore(
		cl.encoder,
		zapcore.AddSync(cl.writer),

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Read the wrapped LoadModule error — 'module not registered' points to a missing/misspelled module ID, other text points to the module's own provisioning.
  2. Correct the core module name or its inline fields.
  3. Rebuild with xcaddy including the plugin that provides the core module.
  4. Remove the core block to use the default core and confirm the rest of the config is valid.

Example fix

// before (json)
"logs": { "log0": { "core": { "badcore": {} } } }

// after
"logs": { "log0": { "core": { "zap.core.sampling": { "interval": "1s" } } } }
Defensive patterns

Strategy: validation

Validate before calling

// before load: verify any custom core module id is registered
for _, coreID := range coreModuleIDs(cfg) {
    if _, err := caddy.GetModule(coreID); err != nil {
        return fmt.Errorf("core module %s not in build: %w", coreID, err)
    }
}

Try / catch

if err := caddy.Validate(cfg); err != nil {
    if strings.Contains(err.Error(), "loading log core module") {
        // core object is invalid: fix module id or inline fields
    }
    return err
}

Prevention

When it happens

Trigger: A logs block with a core { ... } object whose module name is not registered, or whose inline configuration fails the module's own provisioning or validation.

Common situations: Custom core modules (e.g. sampling or third-party cores) omitted from an xcaddy build; typos in the core module name; JSON configs where the core object's module-name key is missing; plugin version drift changing the module's config schema.

Related errors


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