pentaho/pentaho-kettle · error · KettleException

RepositoryMeta.Error.OpeningFile

Error message

RepositoryMeta.Error.OpeningFile

What it means

RepositoriesMeta.readData throws KettleException with RepositoryMeta.Error.OpeningFile when the specified repositories.xml file does not exist AND the classpath fallback resource /org/pentaho/di/repository/repositories.xml is also absent. The original FileNotFoundException is chained.

Solutions

  1. Create repositories.xml by launching Spoon once and connecting to a repository, or copy one from a working machine
  2. Point the loader at an existing file path (or set KETTLE_HOME) so the File exists
  3. Ship a default repositories.xml on the classpath for embedded/headless deployments
  4. Verify the absolute path passed to readData with File.exists() beforehand

Example fix

// before
RepositoriesMeta repos = new RepositoriesMeta();
repos.readData(new File("/nonexistent/repositories.xml"));
// after
File f = new File(System.getProperty("user.home") + "/.kettle/repositories.xml");
if (!f.exists()) throw new IllegalStateException("Run Spoon once to create repositories.xml at " + f);
repos.readData(f);
Defensive patterns

Strategy: validation

Validate before calling

java.io.File f = new java.io.File(repoXmlPath);
if (!f.isFile()) {
  // fall back to the default location
  f = new java.io.File(System.getProperty("user.home") + "/.kettle/repositories.xml");
  if (!f.isFile()) throw new IllegalStateException("repositories.xml not found; run Spoon once or set KETTLE_HOME");
}
RepositoriesMeta meta = new RepositoriesMeta();
meta.readData(f);

Type guard

static boolean repositoriesFileExists(java.io.File f) { return f != null && f.isFile() && f.length() > 0; }

Try / catch

try {
  reposMeta.readData(file);
} catch (KettleException e) {
  if (e.getCause() instanceof java.io.FileNotFoundException) {
    throw new IllegalStateException("repositories.xml missing at " + file.getAbsolutePath() + " — create it via Spoon or ship it on the classpath", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling readData/loadRepositoryInfo with a File that does not exist on disk and no default repositories.xml packaged on the classpath.

Common situations: First run on a machine where Spoon was never started (no ~/.kettle/repositories.xml); wrong KETTLE_HOME pointing to an empty directory; typo in the repositories file path.

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/bfb955e05f476bc4. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/repository/RepositoriesMeta.java:211

    }

    if ( log.isBasic() ) {
      log.logBasic( BaseMessages.getString( PKG, "RepositoryMeta.Log.ReadingXMLFile", file.getAbsoluteFile() ) );
    }

    try {
      // Check and open XML document
      DocumentBuilderFactory dbf = XMLParserFactoryProducer.createSecureDocBuilderFactory();
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc;
      try {
        doc = db.parse( file );
      } catch ( FileNotFoundException ef ) {
        try ( InputStream is = getClass().getResourceAsStream( "/org/pentaho/di/repository/repositories.xml" ) ) {
          if ( is != null ) {
            doc = db.parse( is );
          } else {
            throw new KettleException( BaseMessages.getString( PKG, "RepositoryMeta.Error.OpeningFile", file.getAbsoluteFile() ), ef );
          }
        }
      }
      parseRepositoriesDoc( doc );
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, "RepositoryMeta.Error.ReadingInfo" ), e );
    }

    return true;
  }

  public String getKettleUserRepositoriesFile() {
    return Const.getKettleUserRepositoriesFile();
  }

  String getKettleLocalRepositoriesFile() {
    return Const.getKettleLocalRepositoriesFile();
  }

View on GitHub (pinned to f3058517a1)