apereo/cas · warning

Error loading resources from bundle

Error message

Error loading resources from bundle: [{}] - [{}]

What it means

AggregateCasThemeSource.createMessageSource scans configured theme resource bundle paths and loads each as a Java properties file into a Spring MessageSource. When reading a bundle throws an IOException (missing file, unreadable file, or stream error), the theme source logs this warning and skips that bundle rather than failing startup. The result is that messages/custom text defined in the skipped bundle will be missing at runtime.

Solutions

  1. Verify each configured theme bundle path exists and is readable at the location CAS resolves it from (classpath vs file path).
  2. Correct the bundle path/basename in cas.properties or the theme properties configuration.
  3. Package the missing properties file into the theme JAR/WAR overlay.
  4. Check file permissions on external theme resource directories.

Example fix

// before
cas.themes.custom-theme.messages-basename=classpath:themes/custom/messages
// after (file actually exists at themes/custom-theme/messages.properties)
cas.themes.custom-theme.messages-basename=classpath:themes/custom-theme/messages
Defensive patterns

Strategy: validation

Validate before calling

// before startup, verify each configured bundle resolves
List.of("classpath:themes/custom-theme/messages").forEach(base -> {
    var path = base.replaceFirst("^classpath:", "");
    if (AggregateCasThemeSource.class.getResource(path + ".properties") == null)
        throw new IllegalStateException("Missing theme bundle: " + base);
});

Prevention

When it happens

Trigger: A configured theme resource bundle path (cas.themes.* bundle locations) points to a properties file that does not exist on the classpath or filesystem, or cannot be opened/read as an InputStream.

Common situations: Custom theme deployed without its messages.properties; typo in bundle path or basename; theme resources packaged in a WAR overlay but path misconfigured; file permissions block read after redeploy.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/a1e3e1cdd6fc25cf. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-themes-core/src/main/java/org/apereo/cas/services/web/AggregateCasThemeSource.java:46

    protected MessageSource createMessageSource(
        @NonNull
        final String basename) {
        val source = new StaticMessageSource();
        source.setParentMessageSource(super.createMessageSource(basename));
        casProperties.getView().getTemplatePrefixes()
            .stream()
            .map(prefix -> Strings.CI.appendIfMissing(prefix, "/").concat(basename).concat(".properties"))
            .filter(ResourceUtils::doesResourceExist)
            .forEach(path -> {
                try (val is = ResourceUtils.getRawResourceFrom(path).getInputStream()) {
                    val properties = new Properties();
                    properties.load(is);
                    properties.forEach((key, value) -> {
                        LOGGER.trace("Loading theme property [{}] from [{}]", key, path);
                        source.addMessage(key.toString(), Locale.ENGLISH, value.toString());
                    });
                } catch (final IOException e) {
                    LOGGER.warn("Error loading resources from bundle: [{}] - [{}]", path, e.getMessage());
                }
            });
        return source;
    }
}

View on GitHub (pinned to e7288fc434)