pentaho/pentaho-kettle · error · KettlePluginException

PLUGIN0001

PLUGIN0001

Error message

Unable to read plugin xml file: {0}:

What it means

registerPluginFromXmlResource parses one plugin XML node and constructs/registers a Plugin. Any exception during that per-plugin processing (missing class attribute, XMLHandler failures, invalid fields) is wrapped in KettlePluginException with the localized message BasePluginType.RuntimeError.UnableToReadPluginXML.PLUGIN0001: 'Unable to read plugin xml file: {0}:'. Only the offending plugin fails; the exception propagates out of registerPlugins for the caller to handle.

Solutions

  1. Open the plugin XML reported via the exception cause and fix malformed or missing attributes (id, class, name).
  2. Remove or update the offending third-party plugin jar from the plugins/ directory.
  3. Check getCause() for the exact attribute/class that failed.
  4. Align the plugin descriptor with the current Kettle plugin XML schema for your version.

Example fix

// before
<plugin id="" class="com.acme.MyStep"/>
// after
<plugin id="MyStep" class="com.acme.MyStep" name="My Step"/>
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-validate a plugin.xml node before registration
Node pluginNode = XMLHandler.getSubNode(root, "plugin");
String id = XMLHandler.getTagAttribute(pluginNode, "id");
String cls = XMLHandler.getTagAttribute(pluginNode, "class");
if (id.isEmpty() || cls.isEmpty()) throw new IllegalStateException("plugin.xml missing id/class");

Try / catch

try {
  pluginType.searchPlugins();
} catch (KettlePluginException e) {
  // PLUGIN0001: inspect cause to find offending plugin XML and attribute
  log.logError("Plugin XML unreadable: " + e.getCause(), e);
}

Prevention

When it happens

Trigger: registerPlugins() -> registerPluginFromXmlResource on a <plugin> node whose attributes are missing/invalid (e.g. no id or class), or whose annotated main class references break during registration.

Common situations: Third-party plugin jars shipping malformed plugin.xml files; copy-pasted plugin descriptors with placeholder attributes; plugins built against an older Kettle plugin schema; duplicated plugin IDs from multiple jars.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/pentaho/di/core/plugins/BasePluginType.java:578

      // process extra types added at runtime
      Map<Class<?>, String> objectMap = getAdditionalRuntimeObjectTypes();
      for ( Map.Entry<Class<?>, String> entry : objectMap.entrySet() ) {
        String clzName = getTagOrAttribute( pluginNode, entry.getValue() );
        classMap.put( entry.getKey(), clzName );
      }

      Plugin plugin =
        new Plugin(
          idAttr.split( "," ), pluginType, mainClassTypesAnnotation.value(), category, description, tooltip,
          iconFilename, false, nativePlugin, classMap, jarFiles, errorHelpFileFull, pluginFolder,
          documentationUrl, casesUrl, forumUrl, suggestion );
      plugin.setDeprecated( deprecated );
      registry.registerPlugin( pluginType, plugin );

      return plugin;
    } catch ( Exception e ) {
      throw new KettlePluginException( BaseMessages.getString(
        PKG, "BasePluginType.RuntimeError.UnableToReadPluginXML.PLUGIN0001" ), e );
    }
  }

  protected String getTagOrAttribute( Node pluginNode, String tag ) {
    String string = XMLHandler.getTagValue( pluginNode, tag );
    if ( string == null ) {
      string = XMLHandler.getTagAttribute( pluginNode, tag );
    }
    return string;
  }

  /**
   *
   * @param input
   * @param localizedMap
   * @return
   */

View on GitHub (pinned to f3058517a1)