pentaho/pentaho-kettle · error · KettleException

MODIFY_DATABASE : repository is read-only

Error message

MODIFY_DATABASE : repository is read-only

What it means

validateAction throws this when a MODIFY_DATABASE operation is requested but the file repository capabilities report read-only. All shared-object modifications (database connections) pass through this guard before touching disk. It protects the repository from unintended changes.

Solutions

  1. Reconfigure the connection as read-write (read-only=false).
  2. Move the database connection definition to a repository instance opened with write capabilities.
  3. Grant write permissions to the repository folder for the running user.
  4. Export the DatabaseMeta to XML instead of persisting to the read-only repository.

Example fix

// before
repoMeta.setReadOnly(true);
repo.save(databaseMeta, versionComment, null, true);
// after
repoMeta.setReadOnly(false);
repo.save(databaseMeta, versionComment, null, true);
Defensive patterns

Strategy: try-catch

Validate before calling

if (repository.getSecurityProvider().isReadOnly()) {
  throw new IllegalStateException("Repository read-only; cannot modify database meta");
}

Type guard

boolean writable = repo != null && repo.getSecurityProvider() != null
    && !repo.getSecurityProvider().isReadOnly();

Try / catch

try {
  repo.save(databaseMeta, comment, null, true);
} catch (KettleException e) {
  if (e.getMessage() != null && e.getMessage().contains("MODIFY_DATABASE")) {
    // reopen read-write or export to XML fallback
  } else { throw e; }
}

Prevention

When it happens

Trigger: Saving, updating or renaming a DatabaseMeta through KettleFileRepository.save / saveDatabaseElement while the repository is in read-only mode.

Common situations: Browsing a shared repository mounted read-only, connecting with read-only repository meta in Spoon, or automated scripts writing connection definitions to a locked repository.

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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/repository/filerep/KettleFileRepositorySecurityProvider.java:85

          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:
          break;

        case MODIFY_SLAVE_SERVER:
        case MODIFY_CLUSTER_SCHEMA:
        case MODIFY_PARTITION_SCHEMA:
          if ( capabilities.isReadOnly() ) {
            throw new KettleException( operation + " : repository is read-only" );
          }
          break;
        case DELETE_SLAVE_SERVER:

View on GitHub (pinned to f3058517a1)