{"record":{"id":"98486ab74f58c3b5","repo":"pentaho/pentaho-kettle","slug":"unable-to-load-native-plugins-xmlfile","errorCode":null,"errorMessage":"Unable to load native plugins '${xmlFile}'","messagePattern":"Unable to load native plugins '(.+?)'","errorType":"exception","errorClass":"KettlePluginException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/plugins/BasePluginType.java","lineNumber":215,"sourceCode":"        xmlFile = alternative;\n      }\n    }\n\n    // Load the plugins for this file...\n    //\n    InputStream inputStream = null;\n    try {\n      inputStream = getResAsStreamExternal( xmlFile );\n      if ( inputStream == null ) {\n        inputStream = getResAsStreamExternal( \"/\" + xmlFile );\n      }\n\n      if ( !Utils.isEmpty( getAlternativePluginFile() ) && inputStream == null && !Utils.isEmpty( alternative ) ) {\n        // Retry to load a regular file...\n        try {\n          inputStream = getFileInputStreamExternal( xmlFile );\n        } catch ( Exception e ) {\n          throw new KettlePluginException( \"Unable to load native plugins '\" + xmlFile + \"'\", e );\n        }\n      }\n\n      if ( inputStream == null ) {\n        if ( isReturn() ) {\n          return;\n        } else {\n          throw new KettlePluginException( \"Unable to find native plugins definition file: \" + xmlFile );\n        }\n      }\n\n      registerPlugins( inputStream );\n\n    } catch ( KettleXMLException e ) {\n      throw new KettlePluginException( \"Unable to read the kettle XML config file: \" + xmlFile, e );\n    } finally {\n      IOUtils.closeQuietly( inputStream );\n    }","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/plugins/BasePluginType.java#L197-L233","documentation":"BasePluginType.registerNatives loads the plugin type's native plugin XML definition (e.g. steps/type-list.xml). If the primary classpath resource can't be read and an alternative plugin file is configured, it retries via getFileInputStreamExternal(xmlFile); if that retry also fails, KettlePluginException is thrown wrapping the underlying IO problem. This means the plugin system cannot read its built-in plugin catalog.","triggerScenarios":"registerNatives (invoked by searchPlugins()) where an alternative plugin file is set, the classpath resource stream is null, and getFileInputStreamExternal throws — e.g. the alternative path doesn't exist or is unreadable.","commonSituations":"KETTLE_*/alternative plugin config pointing at a missing or mis-spelled file; corrupted installation where the jar containing the native plugin XML is absent from the classpath; packaging a shaded jar that dropped plugin XML resources.","solutions":["Fix or remove the alternative plugin file configuration so it points at an existing, readable file.","Verify the kettle-core jar (or plugin type jar) containing the native XML is on the classpath and not corrupted.","Check the wrapped cause (getCause()) for the exact IO error (file not found vs permission).","Reinstall/restore the Pentaho installation directory if built-in resources are missing."],"exampleFix":"// before\nSystem.setProperty(\"KETTLE_PLUGIN_FILE\", \"/opt/wrong/plugins.xml\");\n// after\nSystem.setProperty(\"KETTLE_PLUGIN_FILE\", \"/opt/pentaho/plugins/plugins.xml\"); // existing file","handlingStrategy":"try-catch","validationCode":"String alt = System.getenv().getOrDefault(\"KETTLE_PLUGIN_FILE\", \"\");\nif (!alt.isEmpty() && !new File(alt).canRead()) {\n  throw new IllegalStateException(\"Alternative plugin file unreadable: \" + alt);\n}","typeGuard":"static boolean canReadResource(ClassLoader cl, String path) {\n  try (InputStream in = cl.getResourceAsStream(path)) { return in != null; }\n  catch (Exception e) { return false; }\n}","tryCatchPattern":"try {\n  pluginType.searchPlugins();\n} catch (KettlePluginException e) {\n  log.logError(\"Failed to load native plugins: \" + e.getCause(), e);\n}","preventionTips":["Point any alternative plugin file setting at an existing, readable file or unset it.","Keep the kettle-core jar (with native plugin XMLs) intact on the classpath.","Don't strip XML resources in shaded/assembly packaging.","Check getCause() first — it names the real IO problem."],"tags":["kettle","plugins","classpath","configuration"],"backgroundTag":"file-read-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"}