{"record":{"id":"9ed7e14b0b5d4d6b","repo":"pentaho/pentaho-kettle","slug":"unable-to-load-kettle-database-repository-meta-object-9ed7e1","errorCode":null,"errorMessage":"Unable to load Kettle database repository meta object","messagePattern":"Unable to load Kettle database repository meta object","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/PurRepositoryMeta.java","lineNumber":97,"sourceCode":"  public void loadXML( Node repnode, List<DatabaseMeta> databases ) throws KettleException {\n    super.loadXML( repnode, databases );\n    try {\n      String url = XMLHandler.getTagValue( repnode, \"repository_location_url\" );\n      // remove trailing slash\n      String urlTrim = url.endsWith( \"/\" ) ? url.substring( 0, url.length() - 1 ) : url;\n      this.repositoryLocation = new PurRepositoryLocation( urlTrim );\n      this.versionCommentMandatory =\n          \"Y\".equalsIgnoreCase( XMLHandler.getTagValue( repnode, \"version_comment_mandatory\" ) );\n      this.authMethod = XMLHandler.getTagValue( repnode, \"auth_method\" );\n      // Normalize null or blank/whitespace auth method to default for backward compatibility\n      if ( this.authMethod == null || this.authMethod.trim().isEmpty() ) {\n        this.authMethod = AUTH_METHOD_USERNAME_PASSWORD;\n      }\n      setSsoProviderName( XMLHandler.getTagValue( repnode, \"sso_provider_name\" ) );\n      setSsoAuthorizationUri( XMLHandler.getTagValue( repnode, \"sso_authorization_uri\" ) );\n      setSsoRegistrationId( XMLHandler.getTagValue( repnode, \"sso_registration_id\" ) );\n    } catch ( Exception e ) {\n      throw new KettleException( \"Unable to load Kettle database repository meta object\", e );\n    }\n  }\n\n  public RepositoryCapabilities getRepositoryCapabilities() {\n    return new RepositoryCapabilities() {\n      public boolean supportsUsers() {\n        return true;\n      }\n\n      public boolean managesUsers() {\n        return true;\n      }\n\n      public boolean isReadOnly() {\n        return false;\n      }\n\n      public boolean supportsRevisions() {","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/PurRepositoryMeta.java#L79-L115","documentation":"PurRepositoryMeta.loadXML() parses the XML node describing a Pentaho PUR repository connection and throws this KettleException when any exception occurs during parsing (malformed XML, missing nodes, or unexpected values). It wraps the original exception so repository metadata cannot be silently half-loaded. The failure means the repository meta object (connection definition) could not be reconstructed from XML.","triggerScenarios":"Calling loadXML on an XML node that is not a valid PUR repository node: repnode is null, required child tags are absent/corrupt, or XMLHandler.getTagValue throws due to malformed XML structure.","commonSituations":"Hand-edited or corrupted ~/.kettle/repositories.xml, XML produced by a different Pentaho/Kettle version with a different node schema, truncated files, or repository definitions migrated between servers.","solutions":["Validate and repair the repository definition XML (repositories.xml or the node passed to loadXML); back it up and re-create the repository connection in Spoon.","Check the wrapped cause exception (getCause()) to find the exact parse failure.","Ensure the Kettle/Pentaho version writing the XML matches the version reading it; re-export the repository metadata from the correct version.","Confirm the XML node name and structure match what the current PurRepositoryMeta.loadXML expects (repnode with sso_provider_name, sso_authorization_uri, etc.)."],"exampleFix":"// before\nString xml = readRepositoriesXml(); // possibly corrupted/hand-edited\nrepoMeta.loadXML( XMLHandler.getSubNode( XMLHandler.loadXMLString( xml ), \"repository\" ) );\n// after\nString xml = readRepositoriesXmlFromBackupOrRecreate();\nNode root = XMLHandler.loadXMLString( xml );\nNode repnode = XMLHandler.getSubNode( root, \"repository\" );\nif ( repnode == null ) {\n  throw new KettleException( \"Repository node missing from repositories.xml - re-create the repository connection\" );\n}\nrepoMeta.loadXML( repnode );","handlingStrategy":"try-catch","validationCode":"Node repnode = XMLHandler.getSubNode( root, \"repository\" );\nif ( repnode == null ) throw new KettleException( \"Repository XML node missing\" );","typeGuard":"boolean isValidRepoNode( Node n ) { return n != null && XMLHandler.getTagValue( n, \"description\" ) != null; }","tryCatchPattern":"try {\n  repoMeta.loadXML( repnode );\n} catch ( KettleException e ) {\n  logError( \"Repository meta load failed: \" + e.getCause(), e );\n  repoMeta = recreateRepositoryMeta();\n}","preventionTips":["Do not hand-edit repositories.xml; manage connections via Spoon","Back up repositories.xml before Kettle upgrades","Validate XML well-formedness before passing to loadXML","Keep writer and reader Kettle versions aligned"],"tags":["xml","repository","parsing","pentaho-kettle"],"backgroundTag":"json-parse-error","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}