caddyserver/caddy · error

DNS module does not implement the most common libdns interfa

Error message

DNS module does not implement the most common libdns interfaces: %T

What it means

The configured global DNS provider loaded successfully but its type does not simultaneously implement libdns.RecordAppender, RecordDeleter, RecordGetter, and RecordSetter. Caddy requires the most common libdns interfaces because the same provider instance may be used for ACME DNS challenges, on-demand cert management, and DNS record manipulation. This is a compile-time property of the module's Go type, so it indicates an incompatible or incomplete plugin.

Source

Thrown at modules/caddytls/tls.go:191

	t.serverNamesMu = new(sync.Mutex)

	// set up default DNS module, if any, and make sure it implements all the
	// common libdns interfaces, since it could be used for a variety of things
	// (do this before provisioning other modules, since they may rely on this)
	if len(t.DNSRaw) > 0 {
		dnsMod, err := ctx.LoadModule(t, "DNSRaw")
		if err != nil {
			return fmt.Errorf("loading overall DNS provider module: %v", err)
		}
		switch dnsMod.(type) {
		case interface {
			libdns.RecordAppender
			libdns.RecordDeleter
			libdns.RecordGetter
			libdns.RecordSetter
		}:
		default:
			return fmt.Errorf("DNS module does not implement the most common libdns interfaces: %T", dnsMod)
		}
		t.dns = dnsMod
	}

	// set up a new certificate cache; this (re)loads all certificates
	cacheOpts := certmagic.CacheOptions{
		GetConfigForCert: func(cert certmagic.Certificate) (*certmagic.Config, error) {
			return t.getConfigForName(cert.Names[0]), nil
		},
		Logger: t.logger.Named("cache"),
	}
	if t.Automation != nil {
		cacheOpts.OCSPCheckInterval = time.Duration(t.Automation.OCSPCheckInterval)
		cacheOpts.RenewCheckInterval = time.Duration(t.Automation.RenewCheckInterval)
	}
	if t.Cache != nil {
		cacheOpts.Capacity = t.Cache.Capacity
	}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Update the DNS plugin to a release compatible with your Caddy version (interfaces must match current libdns)
  2. Rebuild with xcaddy so plugin and core resolve to one consistent libdns version: 'xcaddy build --with github.com/caddy-dns/<provider>@latest'
  3. If you maintain the module, implement all four interfaces: RecordAppender, RecordDeleter, RecordGetter, RecordSetter

Example fix

// before: plugin only implements GetRecords/AppendRecords
// after: add the missing methods to satisfy all interfaces
type Provider struct{}

func (p *Provider) GetRecords(ctx context.Context, zone string) ([]libdns.Record, error) { ... }
func (p *Provider) AppendRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error) { ... }
func (p *Provider) DeleteRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error) { ... }
func (p *Provider) SetRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error) { ... }
Defensive patterns

Strategy: validation

Validate before calling

go build ./... && go vet ./...  # in the plugin repo
# compile-time guard inside a custom DNS module:
var _ interface {
	libdns.RecordAppender
	libdns.RecordDeleter
	libdns.RecordGetter
	libdns.RecordSetter
} = (*Provider)(nil)

Type guard

func implementsCommonLibdns(p any) bool {
	switch p.(type) {
	case interface {
		libdns.RecordAppender
		libdns.RecordDeleter
		libdns.RecordGetter
		libdns.RecordSetter
	}:
		return true
	}
	return false
}

Prevention

When it happens

Trigger: Configuring tls.dns with a module that only implements a narrower interface set (e.g. a challenge-only shim that implements just dns01solver.Provider, or a libdns plugin pinned to an old libdns API version where method signatures changed). The type switch at tls.go:185 fails for that Go type.

Common situations: A third-party DNS plugin built against an older github.com/libdns/libdns major version (interface signatures changed) and compiled with xcaddy against a newer Caddy; hand-written DNS provider modules that omit one of the four record methods.

Related errors


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