pentaho/pentaho-kettle · error · KettleException
DELETE_JOB : repository is read-only
Error message
DELETE_JOB : repository is read-only
What it means
KettleFileRepositorySecurityProvider.validateAction throws this KettleException when a DELETE_JOB operation is attempted against a file-based repository that was opened in read-only mode. The security provider is consulted before every repository mutation, so any delete of a job is rejected up front based on repository capabilities. It is a deliberate guard, not a corruption or I/O failure.
Solutions
- Reconnect to the repository with a read-write configuration (read-only=false in KettleFileRepositoryMeta / connect call).
- Ensure the repository directory is on a writable filesystem and the OS user has write permissions.
- Perform the delete with an admin/read-write connection in a maintenance session.
- If deletion is genuinely not allowed, change the code path to not attempt DELETE_JOB and surface the capability to the user.
Example fix
// before
repository.connect("user", "pass"); // meta flags read-only
repository.deleteJob(jobId);
// after
repositoryMeta.setReadOnly(false);
repository.connect("user", "pass");
repository.deleteJob(jobId); Defensive patterns
Strategy: try-catch
Validate before calling
if (repository.getSecurityProvider() instanceof KettleFileRepositorySecurityProvider
&& repository.getSecurityProvider().isReadOnly()) {
throw new IllegalStateException("Repository is read-only; cannot delete job");
} Type guard
boolean canModify(org.pentaho.di.repository.Repository repo) {
try { return !repo.getSecurityProvider().isReadOnly(); }
catch (Exception e) { return false; }
} Try / catch
try {
repository.deleteJob(jobId);
} catch (KettleException e) {
if (e.getMessage() != null && e.getMessage().contains("repository is read-only")) {
// reopen repository read-write or notify user
} else { throw e; }
} Prevention
- Check securityProvider.isReadOnly() before any repository mutation.
- Ensure the repository directory is on a writable filesystem/mount.
- Keep a read-write connection for maintenance tasks; use read-only connections only for browsing.
- Surface read-only capability in UI before offering delete actions.
When it happens
Trigger: Calling KettleFileRepository.deleteJob / deleteRepositoryObject when the repository was connected with a KettleFileRepositoryCapabilities whose isReadOnly() is true, or via KettleFileRepositoryMeta configured read-only.
Common situations: Opening a repository directory on a read-only filesystem or shared/network mount, users with view-only repository connections (e.g. read-only shared folders), or code connecting with the read-only flag set accidentally.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Could not retrieve version history of object with path
- DELETE_DATABASE : repository is read-only
- DELETE_TRANSFORMATION : repository is read-only
- " + element.getName() + " has a null id
- ERROR_0002_Cannot_Load_Job_From_Repository
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/1c1d106980907557.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/repository/filerep/KettleFileRepositorySecurityProvider.java:75
if ( capabilities.isReadOnly() ) {
throw new KettleException( operation + " : repository is read-only" );
}
break;
case EXECUTE_TRANSFORMATION:
break;
case LOCK_TRANSFORMATION:
break;
case READ_JOB:
break;
case MODIFY_JOB:
if ( capabilities.isReadOnly() ) {
throw new KettleException( operation + " : repository is read-only" );
}
break;
case DELETE_JOB:
if ( capabilities.isReadOnly() ) {
throw new KettleException( operation + " : repository is read-only" );
}
break;
case EXECUTE_JOB:
break;
case LOCK_JOB:
break;
case MODIFY_DATABASE:
if ( capabilities.isReadOnly() ) {
throw new KettleException( operation + " : repository is read-only" );
}
break;
case DELETE_DATABASE:
if ( capabilities.isReadOnly() ) {
throw new KettleException( operation + " : repository is read-only" );
}
break;
case EXPLORE_DATABASE:View on GitHub (pinned to f3058517a1)