{"record":{"id":"bb3c34fa484846f4","repo":"caddyserver/caddy","slug":"loading-tls-storage-module-v","errorCode":null,"errorMessage":"loading TLS storage module: %v","messagePattern":"loading TLS storage module: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/automation.go","lineNumber":200,"sourceCode":"func (ap *AutomationPolicy) Provision(tlsApp *TLS) error {\n\t// replace placeholders in subjects to allow environment variables\n\trepl := caddy.NewReplacer()\n\tsubjects := make([]string, len(ap.SubjectsRaw))\n\tfor i, sub := range ap.SubjectsRaw {\n\t\tsub = repl.ReplaceAll(sub, \"\")\n\t\tsubASCII, err := idna.ToASCII(sub)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"could not convert automation policy subject '%s' to punycode: %v\", sub, err)\n\t\t}\n\t\tsubjects[i] = subASCII\n\t}\n\tap.subjects = subjects\n\n\t// policy-specific storage implementation\n\tif ap.StorageRaw != nil {\n\t\tval, err := tlsApp.ctx.LoadModule(ap, \"StorageRaw\")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"loading TLS storage module: %v\", err)\n\t\t}\n\t\tcmStorage, err := val.(caddy.StorageConverter).CertMagicStorage()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"creating TLS storage configuration: %v\", err)\n\t\t}\n\t\tap.storage = cmStorage\n\t}\n\n\t// we don't store loaded modules directly in the certmagic config since\n\t// policy provisioning may happen more than once (during auto-HTTPS) and\n\t// loading a module clears its config bytes; thus, load the module and\n\t// store them on the policy before putting it on the config\n\n\t// load and provision any cert manager modules\n\tif ap.ManagersRaw != nil {\n\t\tap.hadExplicitManagers = true\n\t\tvals, err := tlsApp.ctx.LoadModule(ap, \"ManagersRaw\")\n\t\tif err != nil {","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/automation.go#L182-L218","documentation":"The automation policy declares a storage module (StorageRaw, e.g. a custom certmagic storage backend) and caddy.Context.LoadModule failed to instantiate/provision it. The wrapped error carries the underlying module's own failure (bad module config, unknown module name, or the module's Provision error).","triggerScenarios":"Setting \"storage\" inside a TLS automation policy to a module name that is not compiled into the binary; a storage module whose Provision rejects its options (bad connection string, unwritable path); JSON type mismatches in the storage module config.","commonSituations":"Using a plugin storage backend (S3, Redis, Consul...) without having built Caddy with that plugin; typo'd module names in JSON config; wrong credentials/endpoints for the storage backend; version drift between plugin and Caddy.","solutions":["Read the wrapped error — it identifies which module failed and why; fix that module's configuration.","If the module is unknown, build Caddy (xcaddy build --with ...) including the storage plugin, or remove the storage block to use default local storage.","Verify credentials, endpoints, and permissions for the storage backend (e.g. S3 bucket write access).","Test the storage config in isolation with the module's own tooling before wiring it into the automation policy."],"exampleFix":"// before: plugin not compiled in\n{\"apps\":{\"tls\":{\"automation\":{\"policies\":[{\"subjects\":[\"example.com\"],\"storage\":{\"module\":\"redis\"}}]}}}}\n\n// after: build with plugin, or use file_system storage\n\"storage\": {\"module\": \"file_system\", \"root\": \"/var/lib/caddy/storage\"}","handlingStrategy":"try-catch","validationCode":"// Confirm the module is present before referencing it.\nif caddy.GetModule(\"caddy.storage.redis\") == nil { // pseudocode; iterate caddy.Modules()\n    return errors.New(\"storage plugin not compiled in; rebuild with xcaddy --with\")\n}","typeGuard":null,"tryCatchPattern":"if err := policy.Provision(tlsApp); err != nil {\n    if strings.Contains(err.Error(), \"loading TLS storage module\") {\n        return fmt.Errorf(\"fix or remove policy storage config: %w\", err)\n    }\n}","preventionTips":["Build custom binaries with xcaddy and pin plugin versions in a checked-in build script.","Run `caddy validate --config Caddyfile --adapter caddyfile` in CI with the production binary.","Keep storage module configs minimal and tested per environment."],"tags":["tls","storage","module-system","configuration"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}