pentaho/pentaho-kettle · error · KettleException
PurRepository.ERROR_0004_DATABASE_UPDATE_ACCESS_DENIED
PurRepository.ERROR_0004_DATABASE_UPDATE_ACCESS_DENIED
Error message
PurRepository.ERROR_0004_DATABASE_UPDATE_ACCESS_DENIED (localized, takes element name; 'access denied' during database update)
What it means
Thrown by PurRepository save/update methods (e.g. updateDatabase) when the underlying repository service reports 'access denied'. The adapter inspects the exception message for 'access denied' and rethrows a friendlier localized error (ERROR_0004_DATABASE_UPDATE_ACCESS_DENIED) including the element name.
Solutions
- Grant the current user write/update permissions on the target repository folder
- Use an account with sufficient privileges for metadata updates
- Ask an administrator to adjust the repository ACL for the shared object
Example fix
// before
repository.updateDatabase(id, databaseMeta); // run by read-only user
// after
// run as a user with write access, or handle:
try { repository.updateDatabase(id, databaseMeta); }
catch (KettleException e) { log.error("Access denied updating database; check permissions", e); } Defensive patterns
Strategy: try-catch
Try / catch
try {
repository.updateDatabase(id, databaseMeta);
} catch (KettleException e) {
if (e.getMessage().contains("ACCESS_DENIED") || e.getMessage().contains("access denied")) {
log.error("No permission to update database " + databaseMeta.getName()
+ "; request write access", e);
}
} Prevention
- Verify the service account has write/update permissions in the repository
- Audit repository ACLs after security policy changes
- Use admin credentials only for metadata updates
When it happens
Trigger: Calling save/update on a database (or other shared element) whose name matches an object in a repository folder where the current user lacks write permission; server ACL denies the update; read-only role used to modify objects.
Common situations: Non-admin users editing shared database connections; repository security policies changed after deployment; connecting with an account lacking metadata update rights.
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.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- AbsSecurityProvider.ERROR_0002_UNABLE_TO_ACCESS_IS_ALLOWED
- AbsSecurityManager.ERROR_0005_INSUFFICIENT_PRIVELEGES
- AbsSecurityProvider.ERROR_0003_UNABLE_TO_ACCESS_GET_ALLOWED_ACTIONS
- AddSequenceMeta.Exception.UnableToReadStepInfo
- AddSequenceMeta.Exception.UnableToSaveStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/875ddf54244ad142.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/PurRepository.java:2388
+ RepositoryObjectType.DATABASE.getExtension() ) ).title( RepositoryFile.DEFAULT_LOCALE,
element.getName() ).createdDate( createdDate ).versioned( VERSION_SHARED_OBJECTS ).build();
file =
pur.createFile( getDatabaseMetaParentFolderId(), file,
new NodeRepositoryFileData( databaseMetaTransformer.elementToDataNode( element ) ), versionComment );
}
// side effects
ObjectId objectId = new StringObjectId( file.getId().toString() );
element.setObjectId( objectId );
element.setObjectRevision( getObjectRevision( objectId, null ) );
if ( element instanceof ChangedFlagInterface ) {
( (ChangedFlagInterface) element ).clearChanged();
}
updateSharedObjectCache( element );
} catch ( Exception e ) {
// determine if there is an "access denied" issue and throw a nicer error message.
if ( e.getMessage().indexOf( "access denied" ) >= 0 ) {
throw new KettleException(
BaseMessages.getString( PKG, "PurRepository.ERROR_0004_DATABASE_UPDATE_ACCESS_DENIED", element.getName() ),
e );
}
} finally {
readWriteLock.writeLock().unlock();
}
}
@Override
public DatabaseMeta loadDatabaseMeta( final ObjectId databaseId, final String versionId )
throws KettleException {
readWriteLock.readLock().lock();
try {
NodeRepositoryFileData
data =
pur.getDataAtVersionForRead( databaseId.getId(), versionId, NodeRepositoryFileData.class );
RepositoryFile file = null;View on GitHub (pinned to f3058517a1)