caddyserver/caddy · error
trust_pool module '%s' is not a certificate pool provider
Error message
trust_pool module '%s' is not a certificate pool provider
What it means
Returned by UnmarshalCaddyfile for client_auth's trust_pool subdirective when the module unmarshaled from tls.ca_pool.source.<name> does not implement the CA interface. Note the message itself is buggy: it formats caMod (a nil-typed interface value) with %s instead of modName, so the name in the message is useless — identify the module from your config instead.
Source
Thrown at modules/caddytls/connpolicy.go:720
if err != nil {
return d.WrapErr(err)
}
ca.TrustedLeafCerts = append(ca.TrustedLeafCerts, ders...)
case "trust_pool":
if len(ca.TrustedCACerts) != 0 {
return d.Err("cannot specify both 'trust_pool' and 'trusted_ca_cert' or 'trusted_ca_cert_file'")
}
if !d.NextArg() {
return d.ArgErr()
}
modName := d.Val()
mod, err := caddyfile.UnmarshalModule(d, "tls.ca_pool.source."+modName)
if err != nil {
return d.WrapErr(err)
}
caMod, ok := mod.(CA)
if !ok {
return fmt.Errorf("trust_pool module '%s' is not a certificate pool provider", caMod)
}
ca.CARaw = caddyconfig.JSONModuleObject(caMod, "provider", modName, nil)
case "verifier":
if !d.NextArg() {
return d.ArgErr()
}
vType := d.Val()
modID := "tls.client_auth.verifier." + vType
unm, err := caddyfile.UnmarshalModule(d, modID)
if err != nil {
return err
}
_, ok := unm.(ClientCertificateVerifier)
if !ok {
return d.Errf("module '%s' is not a caddytls.ClientCertificateVerifier", modID)
}View on GitHub (pinned to 50e54ee279)
Solutions
- Look at the argument after 'trust_pool' in your Caddyfile — that is the module name that failed the check (ignore the garbage in the message itself)
- Run 'caddy list-modules' and verify the tls.ca_pool.source.<name> module implements the CA pool provider interface
- Fix or update the plugin so its module implements CA (Certificates/CACertificates etc.), or use a stock provider
- Use 'file', 'inline', 'pki', or 'combined' if they fit your use case
Example fix
# before
client_auth {
trust_pool mybrokenplugin
}
# after
client_auth {
trust_pool file /etc/caddy/client-cas.pem
} Defensive patterns
Strategy: type-guard
Validate before calling
# Before deploying a config with a custom trust_pool provider: caddy list-modules --packages caddytls | grep 'ca_pool'
Type guard
// Compile-time guard for plugin authors implementing a trust pool source: var _ caddytls.CA = (*MyPoolSource)(nil)
Prevention
- Plugin authors: add the CA interface guard so this failure is impossible to compile
- Operators: use stock providers (file, inline, pki, combined) unless a plugin is required
- On plugin upgrades, run 'caddy list-modules' and smoke-test client_auth before rolling out
When it happens
Trigger: Writing 'trust_pool <name>' where <name> resolves to a module registered under tls.ca_pool.source but not implementing CA (e.g. a plugin registering a colliding name, or an internal module misused here). Typically only possible with custom builds, since stock source modules (file, inline, combined, root, pki) all implement CA.
Common situations: xcaddy plugin registering a module in the ca_pool namespace without implementing the CA interface; typo happens to match a non-CA module; version skew after a plugin changed its module type.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- two policies with same match criteria have conflicting clien
- source %T returned a nil certificate
- provisioning client CA: %v
- consolidating TLS connection policies for server %d: %v
- server listening on %v is HTTP, but attempts to configure TL
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/0fa35a30991c9514.
Report an issue: GitHub.