pentaho/pentaho-kettle · error · KettlePluginException

Unable to find native plugins definition file

Error message

Unable to find native plugins definition file: ${xmlFile}

What it means

After attempting to load the native plugin definition XML from the classpath, registerNatives checks whether it obtained an input stream. If it is still null — the resource was never found — and the plugin type is not marked 'return quietly' (isReturn() false), KettlePluginException 'Unable to find native plugins definition file' is thrown. The plugin type cannot enumerate any native plugins.

Solutions

  1. Ensure the jar containing the native plugin XML (e.g. kettle-core for standard types) is on the classpath.
  2. Verify the resource path/name expected by the plugin type matches what is packaged (check the plugin type's constructor).
  3. If the plugin type genuinely has no native XML, call setReturn(true) so absence is tolerated.
  4. Check packaging config (maven-shade/assembly) isn't filtering out *.xml descriptors.

Example fix

// before
<artifactSet><excludes><exclude>org.pentaho.di:*</exclude></excludes></artifactSet>
// after
<!-- keep kettle-core so native plugin XMLs stay on classpath -->
Defensive patterns

Strategy: validation

Validate before calling

String res = "org/pentaho/di/core/steps/type-list.xml"; // per plugin type
if (getClass().getClassLoader().getResource(res) == null) {
  throw new IllegalStateException("Native plugin definition missing from classpath: " + res);
}

Type guard

static boolean hasPluginDescriptor(String resource) {
  return Thread.currentThread().getContextClassLoader().getResource(resource) != null;
}

Try / catch

try {
  pluginType.searchPlugins();
} catch (KettlePluginException e) {
  log.logError("Native plugin definition not found: " + xmlFile, e);
}

Prevention

When it happens

Trigger: searchPlugins() -> registerNatives() where the XML resource for the plugin type does not exist on the classpath (resource name changed, jar missing) and the type doesn't tolerate absence.

Common situations: Building a minimal/shaded classpath that excluded plugin descriptor XMLs; relocating/renaming packages so resource lookups miss; custom plugin type whose XML filename doesn't match; removing jars from lib/ that carry the descriptors.

Understand the failure class

Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.

Related errors


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

Appendix: source

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

      inputStream = getResAsStreamExternal( xmlFile );
      if ( inputStream == null ) {
        inputStream = getResAsStreamExternal( "/" + xmlFile );
      }

      if ( !Utils.isEmpty( getAlternativePluginFile() ) && inputStream == null && !Utils.isEmpty( alternative ) ) {
        // Retry to load a regular file...
        try {
          inputStream = getFileInputStreamExternal( xmlFile );
        } catch ( Exception e ) {
          throw new KettlePluginException( "Unable to load native plugins '" + xmlFile + "'", e );
        }
      }

      if ( inputStream == null ) {
        if ( isReturn() ) {
          return;
        } else {
          throw new KettlePluginException( "Unable to find native plugins definition file: " + xmlFile );
        }
      }

      registerPlugins( inputStream );

    } catch ( KettleXMLException e ) {
      throw new KettlePluginException( "Unable to read the kettle XML config file: " + xmlFile, e );
    } finally {
      IOUtils.closeQuietly( inputStream );
    }
  }

  @VisibleForTesting
  protected String getPropertyExternal( String key, String def ) {
    return System.getProperty( key, def );
  }

  @VisibleForTesting

View on GitHub (pinned to f3058517a1)