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

  1. Reconnect to the repository with a read-write configuration (read-only=false in KettleFileRepositoryMeta / connect call).
  2. Ensure the repository directory is on a writable filesystem and the OS user has write permissions.
  3. Perform the delete with an admin/read-write connection in a maintenance session.
  4. 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

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


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)