pentaho/pentaho-kettle · error · MissingResourceException

Unable to find properties file for package

Error message

Unable to find properties file for package '${packagePath}' and class '${resourceClass}' in the available locales: ${activeLocales}

What it means

getBundle iterates the active locales looking for a properties resource bundle for a package/class; if no locale yields a bundle, it throws MissingResourceException with 'Unable to find properties file for package ... and class ... in the available locales: ...'. It means the i18n resource file is absent from the classpath for every configured locale.

Solutions

  1. Verify the properties file exists at <packagePath>/messages/messages_<locale>.properties inside the jar (unzip -l plugin.jar | grep properties).
  2. Fix the PKG package string so it matches the location of the messages resources.
  3. Rebuild with Maven so resources are included (check resource filtering/excludes didn't strip .properties).
  4. Ensure the plugin jar is on the classpath (lib/ or plugins/<plugin>/) and no proguard/shade config excludes it.

Example fix

// before
private static final Class<?> PKG = WrongPackage.class; // messages not under this package
// after
private static final Class<?> PKG = MyPlugin.class; // messages/ sits beside MyPlugin.class
// resources: src/main/resources/org/example/myplugin/messages/messages_en_US.properties
Defensive patterns

Strategy: try-catch

Validate before calling

try {
  GlobalMessageUtil.getBundle(locale, packagePath, resourceClass);
} catch (MissingResourceException e) { /* bundle missing on classpath */ }

Type guard

boolean bundlePresent(Class<?> cls) {
  String p = cls.getPackage().getName().replace('.', '/') + "/messages/messages_en.properties";
  return cls.getClassLoader().getResource(p) != null;
}

Try / catch

try {
  msg = BaseMessages.getString(PKG, key);
} catch (MissingResourceException e) {
  log.warn("Missing bundle for " + PKG + ", using key " + key);
  msg = key;
}

Prevention

When it happens

Trigger: BaseMessages.getString(PKG, key) where the package's messages files (e.g. messages/messages_en_US.properties) are missing from the classpath for all active locales — typically because the jar was built without resources or PKG points at a wrong package path.

Common situations: Shading/proguard stripping .properties resources, wrong package name passed as PKG, custom plugin missing its messages folder, renaming packages without moving messages files, classpath misconfiguration in the plugin folder.

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


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/fc20ccfafe056191. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/i18n/GlobalMessageUtil.java:303

  public static ResourceBundle getBundle( final String packagePath, final Class<?> resourceClass )
    throws MissingResourceException {
    final Set<Locale> activeLocales = getActiveLocales();
    for ( final Locale locale : activeLocales ) {
      try {
        return getBundle( locale, packagePath, resourceClass );
      } catch ( MissingResourceException e ) {
        final StringBuilder msg = new StringBuilder();
        msg.append( "Unable to find properties file for package '" ).append( packagePath ).append( "' and class '" )
          .append( resourceClass.getName() ).append( "' in the available locales: " ).append( locale );
        // nothing to do, an exception will be thrown if no bundle is found
        log.warn( msg.toString() );
      }
    }
    final StringBuilder msg = new StringBuilder();
    msg.append( "Unable to find properties file for package '" ).append( packagePath ).append( "' and class '" )
      .append( resourceClass.getName() ).append( "' in the available locales: " ).append(
      Arrays.asList( activeLocales ) );
    throw new MissingResourceException( msg.toString(), resourceClass.getName(),
      packagePath );
  }

  public static ResourceBundle getBundle( Locale locale, String packagePath, Class<?> resourceClass ) {
    return getBundle( locale, packagePath, resourceClass, true );
  }

  /**
   * Returns a {@link ResourceBundle} corresponding to the given {@link Locale} package and resource class. Falls-back
   * on the ROOT {@link Locale}, if the {@code fallbackOnRoot} flag is true and the requested Locale is not available.
   *
   * @param locale         the {@link Locale} for which the {@link ResourceBundle} is being requested
   * @param packagePath
   * @param resourceClass
   * @param fallbackOnRoot if true, and a {@link ResourceBundle} cannot be found for the requested {@link Locale}, falls
   *                       back on the ROOT {@link Locale}
   * @return a {@link ResourceBundle} corresponding to the given {@link Locale} package and resource class
   */

View on GitHub (pinned to f3058517a1)