caddyserver/caddy · error

module not registered: %s

Error message

module not registered: %s

What it means

caddy.GetModule(name) looks a module up by its full namespaced ID in the global registry; if no module with that exact ID was registered at init time, it returns this error. Registration happens only for packages compiled into the binary.

Source

Thrown at modules.go:169

		panic("ModuleInfo.New must return a non-nil module instance")
	}

	modulesMu.Lock()
	defer modulesMu.Unlock()

	if _, ok := modules[string(mod.ID)]; ok {
		panic(fmt.Sprintf("module already registered: %s", mod.ID))
	}
	modules[string(mod.ID)] = mod
}

// GetModule returns module information from its ID (full name).
func GetModule(name string) (ModuleInfo, error) {
	modulesMu.RLock()
	defer modulesMu.RUnlock()
	m, ok := modules[name]
	if !ok {
		return ModuleInfo{}, fmt.Errorf("module not registered: %s", name)
	}
	return m, nil
}

// GetModuleName returns a module's name (the last label of its ID)
// from an instance of its value. If the value is not a module, an
// empty string will be returned.
func GetModuleName(instance any) string {
	var name string
	if mod, ok := instance.(Module); ok {
		name = mod.CaddyModule().ID.Name()
	}
	return name
}

// GetModuleID returns a module's ID from an instance of its value.
// If the value is not a module, an empty string will be returned.
func GetModuleID(instance any) string {

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Use the full module ID including namespace: 'http.handlers.file_server', not 'file_server'.
  2. Run 'caddy list-modules' in the actual binary to see what is registered.
  3. For custom builds, import the package (blank import if needed) so its init() registers the module, or rebuild via xcaddy with the plugin.
  4. Check the module ID against the docs for your Caddy version — IDs occasionally change across majors.

Example fix

// before
info, err := caddy.GetModule("file_server")

// after
info, err := caddy.GetModule("http.handlers.file_server")
Defensive patterns

Strategy: validation

Validate before calling

// check registration before use
if _, err := caddy.GetModule(fullModuleID); err != nil {
    return fmt.Errorf("build is missing module %s — rebuild with xcaddy or fix the ID: %w", fullModuleID, err)
}

Try / catch

info, err := caddy.GetModule(id)
if err != nil {
    if strings.Contains(err.Error(), "module not registered") {
        // fall back to a registered alternative or fail the run with a clear message
    }
    return err
}

Prevention

When it happens

Trigger: Calling caddy.GetModule with a misspelled or non-existent module ID; looking up a standard module in a custom build that does not import modules/standard; looking up a plugin module without having built with xcaddy.

Common situations: Custom minimal builds that omit standard imports; code or configs referencing a module renamed between Caddy versions; plugins looked up by short name instead of full ID (e.g. 'file_server' instead of 'http.handlers.file_server').

Related errors


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