{"record":{"id":"15c0c808f90c1852","repo":"apereo/cas","slug":"could-not-add-template-prefix-s-to-resolver","errorCode":null,"errorMessage":"Could not add template prefix '%s' to resolver: [%s]","messagePattern":"Could not add template prefix '(.+?)' to resolver: \\[(.+?)\\]","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-thymeleaf/src/main/java/org/apereo/cas/config/CasThymeleafAutoConfiguration.java","lineNumber":167,"sourceCode":"        templatePrefixes.forEach(prefix -> {\n            try {\n                val prefixPath = prefix.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX)\n                    ? prefix\n                    : ResourceUtils.getFile(prefix).getCanonicalPath();\n                val viewPath = Strings.CI.appendIfMissing(prefixPath, \"/\");\n                val theme = prefix.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX)\n                    ? new ThemeClassLoaderTemplateResolver(themeResolver)\n                    : new ThemeFileTemplateResolver(casProperties, themeResolver);\n                configureTemplateViewResolver(theme, thymeleafProperties);\n                theme.setPrefix(Strings.CI.removeStart(viewPath, ResourceUtils.CLASSPATH_URL_PREFIX) + \"themes/%s/\");\n                chain.addResolver(theme);\n\n                val template = prefix.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX) ? new ClassLoaderTemplateResolver() : new FileTemplateResolver();\n                configureTemplateViewResolver(template, thymeleafProperties);\n                template.setPrefix(Strings.CI.removeStart(viewPath, ResourceUtils.CLASSPATH_URL_PREFIX));\n                chain.addResolver(template);\n            } catch (final Exception e) {\n                LoggingUtils.warn(LOGGER,\n                    String.format(\"Could not add template prefix '%s' to resolver: [%s]\", prefix, e.getMessage()), e);\n            }\n        });\n\n        chain.addResolver(themeClassLoaderTemplateResolver);\n        chain.addResolver(classLoaderTemplateResolver);\n        chain.initialize();\n        return chain;\n    }\n\n    @Bean\n    @ConditionalOnMissingBean(name = \"themeClassLoaderTemplateResolver\")\n    @RefreshScope(proxyMode = ScopedProxyMode.DEFAULT)\n    public ITemplateResolver themeClassLoaderTemplateResolver(final ThymeleafProperties thymeleafProperties,\n                                                              @Qualifier(\"themeResolver\") final ThemeResolver themeResolver) {\n        val themeCp = new ThemeClassLoaderTemplateResolver(themeResolver);\n        configureTemplateViewResolver(themeCp, thymeleafProperties);\n        themeCp.setPrefix(\"templates/%s/\");","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-thymeleaf/src/main/java/org/apereo/cas/config/CasThymeleafAutoConfiguration.java#L149-L185","documentation":"CasThymeleafChainingTemplateViewResolver setup in CasThymeleafAutoConfiguration.iterates over configured view/template paths and, for each prefix, creates a ClassLoaderTemplateResolver or FileTemplateResolver and adds it to the resolver chain. If constructing/configuring the resolver for a prefix throws, the failure is logged with this message and that prefix is skipped; remaining resolvers (theme and default classpath resolvers) still get added.","triggerScenarios":"An exception is thrown while creating/configuring the template resolver for a configured prefix — e.g. the view path is malformed, an invalid URL/resource prefix, or resolver configuration fails for the given thymeleaf properties.","commonSituations":"Typo or unsupported scheme in a configured template prefix (e.g. bad cas.view.template-prefixes entry); directory expected on disk missing so FileTemplateResolver setup/validation fails; classpath prefix spelled incorrectly.","solutions":["Fix the offending template prefix entry in configuration (cas.view.template-prefixes or theme view paths).","Ensure filesystem-based prefixes point to existing, readable directories.","Use ResourceUtils.CLASSPATH_URL_PREFIX (classpath:) only for resources actually on the classpath.","Check the chained exception (stack trace logged alongside) for the root resolver error."],"exampleFix":"// before\ncas.view.template-prefixes[0]=file:/etc/cas/templates/temlates/\n// after\ncas.view.template-prefixes[0]=file:/etc/cas/templates/templates/","handlingStrategy":"validation","validationCode":"// validate each configured prefix before startup\ncasProperties.getView().getTemplatePrefixes().forEach(p -> {\n    if (p.startsWith(\"file:\") && !java.nio.file.Files.isDirectory(java.nio.file.Path.of(URI.create(p))))\n        LOGGER.warn(\"Template prefix is not a directory: {}\", p);\n});","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate template prefix paths in deployment scripts.","Use classpath: prefixes only for resources bundled in the WAR.","Keep overlay directory structure consistent across environments."],"tags":["thymeleaf","view-resolver","template","configuration"],"backgroundTag":"invalid-config-value","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}