{"record":{"id":"b00399d31cb582af","repo":"caddyserver/caddy","slug":"loading-template-extensions-v","errorCode":null,"errorMessage":"loading template extensions: %v","messagePattern":"loading template extensions: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddyhttp/templates/templates.go","lineNumber":415,"sourceCode":"type CustomFunctions interface {\n\t// CustomTemplateFunctions should return the mapping from custom function names to implementations.\n\tCustomTemplateFunctions() template.FuncMap\n}\n\n// CaddyModule returns the Caddy module information.\nfunc (Templates) CaddyModule() caddy.ModuleInfo {\n\treturn caddy.ModuleInfo{\n\t\tID:  \"http.handlers.templates\",\n\t\tNew: func() caddy.Module { return new(Templates) },\n\t}\n}\n\n// Provision provisions t.\nfunc (t *Templates) Provision(ctx caddy.Context) error {\n\tt.logger = ctx.Logger()\n\tmods, err := ctx.LoadModule(t, \"ExtensionsRaw\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"loading template extensions: %v\", err)\n\t}\n\tfor _, modIface := range mods.(map[string]any) {\n\t\tt.customFuncs = append(t.customFuncs, modIface.(CustomFunctions).CustomTemplateFunctions())\n\t}\n\n\tif t.MIMETypes == nil {\n\t\tt.MIMETypes = defaultMIMETypes\n\t}\n\tif t.FileRoot == \"\" {\n\t\tt.FileRoot = \"{http.vars.root}\"\n\t}\n\treturn nil\n}\n\n// Validate ensures t has a valid configuration.\nfunc (t *Templates) Validate() error {\n\tif len(t.Delimiters) != 0 && len(t.Delimiters) != 2 {\n\t\treturn fmt.Errorf(\"delimiters must consist of exactly two elements: opening and closing\")","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/templates/templates.go#L397-L433","documentation":"Returned by the templates handler's Provision when loading custom template function modules (the 'extensions' field, module namespace http.handlers.templates.functions) fails. The wrapped error typically names the module and reason, such as unknown module or failed provisioning.","triggerScenarios":"A JSON/Caddyfile config for the templates handler that declares extensions (e.g. inline SVG, frappe, placeholders custom modules) not present in the binary, or whose own Provision fails.","commonSituations":"Using a third-party template extension plugin without building Caddy with xcaddy, a plugin version incompatible with the current Caddy core, or a typo in the extension module name in JSON config.","solutions":["Check the wrapped error for the module name and reason","Build with the plugin: `xcaddy build --with <plugin-module-path>`","Verify the extension appears under http.handlers.templates.functions in `caddy list-modules`","Remove the extensions block if the functionality is not needed"],"exampleFix":"# before (binary lacks the plugin)\n# in Caddyfile: templates { extensions frappe }\n\n# after\nxcaddy build --with github.com/benchkram/frp-go/caddyfrp\n# then restart with the same config","handlingStrategy":"validation","validationCode":"caddy list-modules | grep 'http.handlers.templates.functions' || echo 'no template extensions compiled in'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build with xcaddy and verify plugin presence with caddy list-modules before deploying","Pin plugin versions in the xcaddy build command","Validate config against the exact binary that will serve it"],"tags":["caddy","templates","plugins","provisioning"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}