{"record":{"id":"5b11fdfb162bdd1e","repo":"pentaho/pentaho-kettle","slug":"plugin0001","errorCode":"PLUGIN0001","errorMessage":"Unable to read plugin xml file: {0}:","messagePattern":"Unable to read plugin xml file: (.+?):","errorType":"error_code","errorClass":"KettlePluginException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/plugins/BasePluginType.java","lineNumber":578,"sourceCode":"\n      // process extra types added at runtime\n      Map<Class<?>, String> objectMap = getAdditionalRuntimeObjectTypes();\n      for ( Map.Entry<Class<?>, String> entry : objectMap.entrySet() ) {\n        String clzName = getTagOrAttribute( pluginNode, entry.getValue() );\n        classMap.put( entry.getKey(), clzName );\n      }\n\n      Plugin plugin =\n        new Plugin(\n          idAttr.split( \",\" ), pluginType, mainClassTypesAnnotation.value(), category, description, tooltip,\n          iconFilename, false, nativePlugin, classMap, jarFiles, errorHelpFileFull, pluginFolder,\n          documentationUrl, casesUrl, forumUrl, suggestion );\n      plugin.setDeprecated( deprecated );\n      registry.registerPlugin( pluginType, plugin );\n\n      return plugin;\n    } catch ( Exception e ) {\n      throw new KettlePluginException( BaseMessages.getString(\n        PKG, \"BasePluginType.RuntimeError.UnableToReadPluginXML.PLUGIN0001\" ), e );\n    }\n  }\n\n  protected String getTagOrAttribute( Node pluginNode, String tag ) {\n    String string = XMLHandler.getTagValue( pluginNode, tag );\n    if ( string == null ) {\n      string = XMLHandler.getTagAttribute( pluginNode, tag );\n    }\n    return string;\n  }\n\n  /**\n   *\n   * @param input\n   * @param localizedMap\n   * @return\n   */","sourceCodeStart":560,"sourceCodeEnd":596,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/plugins/BasePluginType.java#L560-L596","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Open the plugin XML reported via the exception cause and fix malformed or missing attributes (id, class, name).","Remove or update the offending third-party plugin jar from the plugins/ directory.","Check getCause() for the exact attribute/class that failed.","Align the plugin descriptor with the current Kettle plugin XML schema for your version."],"exampleFix":"// before\n<plugin id=\"\" class=\"com.acme.MyStep\"/>\n// after\n<plugin id=\"MyStep\" class=\"com.acme.MyStep\" name=\"My Step\"/>","handlingStrategy":"try-catch","validationCode":"// Pre-validate a plugin.xml node before registration\nNode pluginNode = XMLHandler.getSubNode(root, \"plugin\");\nString id = XMLHandler.getTagAttribute(pluginNode, \"id\");\nString cls = XMLHandler.getTagAttribute(pluginNode, \"class\");\nif (id.isEmpty() || cls.isEmpty()) throw new IllegalStateException(\"plugin.xml missing id/class\");","typeGuard":null,"tryCatchPattern":"try {\n  pluginType.searchPlugins();\n} catch (KettlePluginException e) {\n  // PLUGIN0001: inspect cause to find offending plugin XML and attribute\n  log.logError(\"Plugin XML unreadable: \" + e.getCause(), e);\n}","preventionTips":["Validate every plugin.xml has required attributes (id, class, name).","Test third-party plugin jars in isolation before adding to plugins/.","Follow the plugin XML schema for your Kettle version.","Remove duplicate plugin IDs across jars."],"tags":["kettle","plugins","xml","plugin-registration"],"backgroundTag":"schema-validation-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}