caddyserver/caddy · error
loading storage module: %v
Error message
loading storage module: %v
What it means
Returned by CA.Provision when ctx.LoadModule(ca, "StorageRaw") fails to load the CA's custom storage module from its raw JSON. LoadModule resolves the module name in the storage namespace and instantiates it; failure means an unknown module name, a module not compiled into the binary, or malformed module JSON. The %v wraps caddy's module-loading error, which names the offending module.
Source
Thrown at modules/caddypki/ca.go:114
}
// Provision sets up the CA.
func (ca *CA) Provision(ctx caddy.Context, id string, log *zap.Logger) error {
ca.mu = new(sync.RWMutex)
ca.log = log.Named("ca." + id)
ca.ctx = ctx
if id == "" {
return fmt.Errorf("CA ID is required (use 'local' for the default CA)")
}
ca.mu.Lock()
ca.ID = id
ca.mu.Unlock()
if ca.StorageRaw != nil {
val, err := ctx.LoadModule(ca, "StorageRaw")
if err != nil {
return fmt.Errorf("loading storage module: %v", err)
}
cmStorage, err := val.(caddy.StorageConverter).CertMagicStorage()
if err != nil {
return fmt.Errorf("creating storage configuration: %v", err)
}
ca.storage = cmStorage
}
if ca.storage == nil {
ca.storage = ctx.Storage()
}
if ca.Name == "" {
ca.Name = defaultCAName
}
if ca.RootCommonName == "" {
ca.RootCommonName = defaultRootCommonName
}
if ca.IntermediateCommonName == "" {View on GitHub (pinned to 50e54ee279)
Solutions
- Check the wrapped error — it says which module failed to load
- Build Caddy with the plugin: xcaddy build --with github.com/.../caddy-storage-redis, or use a build that includes it
- Fix the module name under storage.module to match the plugin's registered caddy.ModuleInfo ID
- Or drop the per-CA storage block to fall back to the global/default storage
Example fix
# before (stock binary) caddy run --config Caddyfile # storage.module: redis → error # after xcaddy build --with github.com/graywindy/caddy-storage-redis ./caddy run --config Caddyfile
Defensive patterns
Strategy: validation
Validate before calling
// Verify the storage plugin is compiled in before loading config:
cmd := exec.Command(caddyBin, "list-modules")
out, _ := cmd.Output()
if !bytes.Contains(out, []byte("caddy.storage."+moduleName)) {
return fmt.Errorf("storage module %q not in build; rebuild with xcaddy --with", moduleName)
} Type guard
// After loading, assert the module implements StorageConverter:
if _, ok := loaded.(caddy.StorageConverter); !ok {
return errors.New("module is not a storage converter")
} Try / catch
// Catch the wrap and point at the build, not the config:
if err := ca.Provision(ctx, id, log); err != nil {
if strings.Contains(err.Error(), "loading storage module") {
return fmt.Errorf("storage plugin missing from build: %v", err)
}
} Prevention
- Build with xcaddy including every storage plugin referenced by config
- Run `caddy list-modules` as a deploy-time smoke test
- Keep the plugin set in sync with the config repo
When it happens
Trigger: Configuring a CA with "storage": {"module": "redis", ...} when the caddy.storage.redis plugin is not built into the custom Caddy binary; a typo in the module key; JSON for the storage module that fails its own unmarshaling. LoadModule returns the error and it is re-wrapped here.
Common situations: Switching from a plugin build (xcaddy) to the stock caddy binary and keeping custom storage config; plugin removed during a build-script cleanup; storage module renamed between plugin versions; env-specific configs where only some builds include the plugin.
Related errors
- creating storage configuration: %v
- loading storage module: %v
- creating storage value: %v
- loading listener wrapper modules: %v
- adding encoding %s: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/84add9c18c2ee85c.
Report an issue: GitHub.