apereo/cas · warning
Theme [ ] for service [ ] cannot be located
Error message
Theme [{}] for service [{}] cannot be located What it means
resolveThemeForService validates the service's configured theme by attempting to load a ResourceBundleMessageSource with the theme name as basename; if doGetBundle returns null the bundle cannot be loaded, so the theme is considered invalid and null is returned (leading to default-theme fallback). This is the concrete check that produces the 'cannot be located' outcome.
Solutions
- Create or restore the theme's properties bundle at the expected basename (classpath:/<theme>/theme.properties).
- Fix the theme name in the service definition to match the actual bundle basename.
- Ensure the theme resource JAR is included in the deployed WAR.
- Check filename case matches the theme name (Linux classpath lookups are case-sensitive).
Example fix
// theme 'mytheme' must ship: // src/main/resources/mytheme/theme.properties logintheme.css=/themes/mytheme/css/login.css
Defensive patterns
Strategy: validation
Validate before calling
// pre-check that the theme basename is loadable
String theme = registeredService.getTheme();
try (var in = getClass().getResourceAsStream("/" + theme + "/theme.properties")) {
if (in == null) throw new IllegalStateException("Theme bundle missing: " + theme);
} Prevention
- Include theme.properties in every custom theme's resources directory.
- Use exact-case theme names to avoid Linux classpath case-sensitivity issues.
- Verify theme JAR is on the runtime classpath after deployment.
When it happens
Trigger: registeredService.getTheme() returns a name for which messageSource.doGetBundle(theme, locale) finds no bundle — the theme properties file is absent from the classpath or its basename does not match.
Common situations: Theme directory exists in views but theme.properties / messages bundle missing; theme packaged in a module not on the runtime classpath; case-sensitivity mismatch in the theme name on Linux.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Custom theme [ ] for service [ ] cannot be located. Falling…
- Error loading resources from bundle
- No registered service is found to match
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/aa3426d89e1cbb6f.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-themes-core/src/main/java/org/apereo/cas/services/web/RegisteredServiceThemeResolver.java:186
protected String resolveThemeForService(final WebBasedRegisteredService registeredService,
final HttpServletRequest request) {
val theme = SpringExpressionLanguageValueResolver.getInstance().resolve(registeredService.getTheme());
if (casProperties.getObject().getView().getTemplatePrefixes()
.stream()
.map(prefix -> Strings.CI.appendIfMissing(prefix, "/").concat(theme).concat(".properties"))
.anyMatch(ResourceUtils::doesResourceExist)) {
LOGGER.trace("Found custom external theme [{}] for service [{}]", theme, registeredService.getName());
return theme;
}
val messageSource = new CasThemeResourceBundleMessageSource();
messageSource.setBasename(theme);
if (messageSource.doGetBundle(theme, request.getLocale()) != null) {
LOGGER.trace("Found custom theme [{}] for service [{}]", theme, registeredService.getName());
return theme;
}
LOGGER.warn("Theme [{}] for service [{}] cannot be located", theme, registeredService.getName());
return null;
}
}
View on GitHub (pinned to e7288fc434)