pentaho/pentaho-kettle · error · KettleException
Unable to get a list of repositories to locate repository
Error message
Unable to get a list of repositories to locate repository '${repositoryName}' What it means
connectRepository(repositoriesMeta...) path: before locating a named repository, the code reads the local repositories.xml list via repositoriesMeta.readData(). If that read throws for any reason, the library throws a KettleException with this message naming the repository it was trying to find. Notably the original exception is swallowed, so the cause is not chained.
Solutions
- Verify ~/.kettle/repositories.xml (or $KETTLE_HOME/.kettle/repositories.xml) exists and is valid XML.
- Run Spoon/Kitchen once as the same user to generate repositories.xml, or copy a known-good one.
- Check file permissions on the .kettle directory for the executing user (service accounts often differ from your login).
- Because the cause is not chained, reproduce readData() separately (new RepositoriesMeta().readData()) to surface the underlying exception.
- If no repository is needed, skip repository connection and run the job from file instead.
Example fix
// before: relying on implicit repositories.xml in service context
Repository repo = execCfg.connectRepository("prod-repo", "user", "pass");
// after: ensure KETTLE_HOME and repositories.xml first
System.setProperty("KETTLE_HOME", "/opt/pentaho/.kettle-home");
RepositoriesMeta rm = new RepositoriesMeta();
rm.readData(); // surface real error here
Repository repo = execCfg.connectRepository(rm, "prod-repo", "user", "pass"); Defensive patterns
Strategy: fallback
Validate before calling
File reposXml = new File(System.getProperty("KETTLE_HOME", System.getProperty("user.home")) + "/.kettle/repositories.xml");
if (!reposXml.canRead()) throw new IllegalStateException("repositories.xml missing/unreadable: " + reposXml); Try / catch
try {
repo = execCfg.connectRepository("prod-repo", user, pass);
} catch (KettleException e) {
if (e.getMessage().startsWith("Unable to get a list of repositories")) {
repo = loadRepositoryFromFileFallback();
} else { throw e; }
} Prevention
- Point KETTLE_HOME explicitly for service accounts and bake a valid repositories.xml into the image.
- Check permissions on .kettle after provisioning.
- Because the cause is swallowed, call RepositoriesMeta.readData() in a health check to surface the real error.
- Avoid repository connections in contexts where none is needed.
When it happens
Trigger: Calling connectRepository(repositoriesMeta, repositoryName, username, password) overload when readData() fails: missing/corrupt ~/.kettle/repositories.xml, unreadable home directory, malformed XML, or inaccessible plugin-providing repository drivers.
Common situations: Headless servers where $HOME/.kettle/repositories.xml is absent; wrong KETTLE_HOME; permissions changed on the user home; corrupted repositories.xml after an upgrade.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Could not connect to repository: ...
- Could not execute specified in a repository since we're not…
- ExecuteJobServlet.Error.UnableToFindRepository
- Invalid repository type
- JobGetMailsFromPOP.Error.AttachmentFolderEmpty
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/767452960816b9f6.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/job/JobExecutionConfiguration.java:491
Node repNode = XMLHandler.getSubNode( trecNode, "repository" );
if ( repNode != null ) {
String repositoryName = XMLHandler.getTagValue( repNode, "name" );
String username = XMLHandler.getTagValue( repNode, "login" );
String password = Encr.decryptPassword( XMLHandler.getTagValue( repNode, "password" ) );
connectRepository( repositoryName, username, password );
}
}
public Repository connectRepository( String repositoryName, String username, String password ) throws KettleException {
// Verify that the repository exists on the slave server...
//
RepositoriesMeta repositoriesMeta = new RepositoriesMeta();
repositoriesMeta.getLog().setLogLevel( log.getLogLevel() );
try {
repositoriesMeta.readData();
} catch ( Exception e ) {
throw new KettleException( "Unable to get a list of repositories to locate repository '" + repositoryName + "'" );
}
return connectRepository( repositoriesMeta, repositoryName, username, password );
}
public Repository connectRepository( RepositoriesMeta repositoriesMeta, String repositoryName, String username, String password ) throws KettleException {
RepositoryMeta repositoryMeta = repositoriesMeta.findRepository( repositoryName );
if ( repositoryMeta == null ) {
log.logBasic( "I couldn't find the repository with name '" + repositoryName + "'" );
return null;
}
Repository rep = PluginRegistry.getInstance().loadClass( RepositoryPluginType.class, repositoryMeta,
Repository.class );
rep.init( repositoryMeta );
try {
rep.connect( username, password );
log.logBasic( "Connected to " + repositoryName + " as " + username );View on GitHub (pinned to f3058517a1)