caddyserver/caddy · error

leaf module '%s' is not a leaf certificate loader

Error message

leaf module '%s' is not a leaf certificate loader

What it means

During Caddyfile parsing of the leaf verifier one-liner form (verifier leaf <inline|file> <arg...>), the unmarshaled module must implement the LeafCertificateLoader interface; if it does not, this error is returned. With stock builds this indicates a broken/misregistered plugin; the %s formats the module value, which may print unhelpfully.

Source

Thrown at modules/caddytls/connpolicy.go:1003

	l.trustedLeafCerts = trustedLeafCertificates
	return nil
}

// UnmarshalCaddyfile implements caddyfile.Unmarshaler.
func (l *LeafCertClientAuth) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
	d.NextArg()

	// accommodate the use of one-liners
	if d.CountRemainingArgs() > 1 {
		d.NextArg()
		modName := d.Val()
		mod, err := caddyfile.UnmarshalModule(d, "tls.leaf_cert_loader."+modName)
		if err != nil {
			return d.WrapErr(err)
		}
		vMod, ok := mod.(LeafCertificateLoader)
		if !ok {
			return fmt.Errorf("leaf module '%s' is not a leaf certificate loader", vMod)
		}
		l.LeafCertificateLoadersRaw = append(
			l.LeafCertificateLoadersRaw,
			caddyconfig.JSONModuleObject(vMod, "loader", modName, nil),
		)
		return nil
	}

	// accommodate the use of nested blocks
	for nesting := d.Nesting(); d.NextBlock(nesting); {
		modName := d.Val()
		mod, err := caddyfile.UnmarshalModule(d, "tls.leaf_cert_loader."+modName)
		if err != nil {
			return d.WrapErr(err)
		}
		vMod, ok := mod.(LeafCertificateLoader)
		if !ok {
			return fmt.Errorf("leaf module '%s' is not a leaf certificate loader", vMod)

View on GitHub (pinned to 50e54ee279)

Solutions

  1. If this is your plugin, implement the full LeafCertificateLoader interface and add a compile-time guard: var _ caddytls.LeafCertificateLoader = (*MyLoader)(nil)
  2. Rebuild with xcaddy against the Caddy version you deploy; mismatched ABI/module interfaces often surface here
  3. If using only stock loaders, rebuild without stale custom plugins and retry
  4. Check the Caddyfile syntax matches: leaf_cert inline <b64der> or leaf_cert file <paths...>
Defensive patterns

Strategy: type-guard

Type guard

var _ caddytls.LeafCertificateLoader = (*MyLoader)(nil)
// implements LoadLeafCertificates() ([]*x509.Certificate, error)
// and LoadLeafCAPrivateKeys() ([]*ecdsa.PrivateKey, error) per interface

Prevention

When it happens

Trigger: A custom module registered under tls.leaf_cert_loader.* that does not implement LoadLeafCertificates()/LoadLeafCAPrivateKeys(); name collisions where the resolved module is the wrong type.

Common situations: XCaddy plugin development where the interface is not yet implemented; plugin builds where an old version of a plugin diverged from the expected interface after a Caddy upgrade.

Understand the failure class

Related errors


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