caddyserver/caddy · error
loading certificate loader modules: %s
Error message
loading certificate loader modules: %s
What it means
Thrown when ctx.LoadModule(t, "CertificatesRaw") fails while provisioning the tls app's 'certificates' section. CertificatesRaw is a map of loader-name -> module config (loaders such as load_files, load_folders, automate). The load fails for any entry whose module name is unknown, whose inline JSON is malformed for the loader, or whose own Provision returns an error.
Source
Thrown at modules/caddytls/tls.go:225
if t.Cache != nil {
cacheOpts.Capacity = t.Cache.Capacity
}
if cacheOpts.Capacity <= 0 {
cacheOpts.Capacity = 10000
}
certCacheMu.Lock()
if certCache == nil {
certCache = certmagic.NewCache(cacheOpts)
} else {
certCache.SetOptions(cacheOpts)
}
certCacheMu.Unlock()
// certificate loaders
val, err := ctx.LoadModule(t, "CertificatesRaw")
if err != nil {
return fmt.Errorf("loading certificate loader modules: %s", err)
}
for modName, modIface := range val.(map[string]any) {
if modName == "automate" {
// special case; these will be loaded in later using our automation facilities,
// which we want to avoid doing during provisioning
if automateNames, ok := modIface.(*AutomateLoader); ok && automateNames != nil {
if t.automateNames == nil {
t.automateNames = make(map[string]struct{})
}
repl := caddy.NewReplacer()
for _, sub := range *automateNames {
t.automateNames[repl.ReplaceAll(sub, "")] = struct{}{}
}
} else {
return fmt.Errorf("loading certificates with 'automate' requires array of strings, got: %T", modIface)
}
continue
}View on GitHub (pinned to 50e54ee279)
Solutions
- Inspect the wrapped error: it names which loader entry failed and why
- Use 'caddy adapt' (or 'caddy validate --config ... --adapter ...') to confirm the config adapts and the loader names match the docs (load_files, load_folders, automate)
- Ensure each load_files entry has both 'certificate' and 'key' string fields with valid paths
- For custom loaders, verify the module is registered via 'caddy list-modules'
Example fix
// before
{"apps": {"tls": {"certificates": {"load_file": [{"certificate": "/certs/a.pem", "key": "/certs/a.key"}]}}}}
// after
{"apps": {"tls": {"certificates": {"load_files": [{"certificate": "/certs/a.pem", "key": "/certs/a.key"}]}}}} Defensive patterns
Strategy: validation
Validate before calling
caddy adapt --config Caddyfile --adapter caddyfile --pretty | jq '.apps.tls.certificates' # confirm only known loader keys: load_files, load_folders, automate
Prevention
- Prefer authoring Caddyfile syntax and adapting to JSON rather than hand-writing the certificates map
- Validate configs in CI with 'caddy validate'
When it happens
Trigger: Configuring tls.certificates with an invalid loader key, e.g. {"certificates": {"load_file": [...]}} (singular, nonexistent) instead of "load_files"; wrong array/object shape for load_files entries (missing 'certificate'/'key' fields); a custom loader module not compiled in.
Common situations: Hand-written JSON configs with typos in loader names; Caddyfile 'tls /path/cert.pem /path/key.pem' translating to load_files with unreadable or misquoted paths; migrating configs between Caddy versions where loader schemas changed.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- consolidating TLS connection policies for server %d: %v
- two policies with same match criteria have conflicting cert
- it is unnecessary to specify the TLS listener wrapper in the
- TLS listener wrapper can only be specified once
- server %s: setting up TLS connection policies: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/05c9915d2129b842.
Report an issue: GitHub.