{"record":{"id":"50ab1819f8c2e03f","repo":"pentaho/pentaho-kettle","slug":"unable-to-load-job-entry-of-type-ftp-from-xml-node","errorCode":null,"errorMessage":"Unable to load job entry of type 'ftp' from XML node","messagePattern":"Unable to load job entry of type 'ftp' from XML node","errorType":"exception","errorClass":"KettleXMLException","httpStatus":null,"severity":"error","filePath":"plugins/ftp-delete/impl/src/main/java/org/pentaho/di/job/entries/ftpdelete/JobEntryFTPDelete.java","lineNumber":324,"sourceCode":"\n      publicpublickey = \"Y\".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, \"publicpublickey\" ) );\n      keyFilename = XMLHandler.getTagValue( entrynode, \"keyfilename\" );\n      keyFilePass = XMLHandler.getTagValue( entrynode, \"keyfilepass\" );\n\n      nr_limit_success = XMLHandler.getTagValue( entrynode, \"nr_limit_success\" );\n      success_condition = XMLHandler.getTagValue( entrynode, \"success_condition\" );\n      copyprevious = \"Y\".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, \"copyprevious\" ) );\n      FTPSConnectionType =\n        FTPSConnection.getConnectionTypeByCode( Const.NVL( XMLHandler.getTagValue(\n          entrynode, \"ftps_connection_type\" ), \"\" ) );\n      socksProxyHost = XMLHandler.getTagValue( entrynode, \"socksproxy_host\" );\n      socksProxyPort = XMLHandler.getTagValue( entrynode, \"socksproxy_port\" );\n      socksProxyUsername = XMLHandler.getTagValue( entrynode, \"socksproxy_username\" );\n      socksProxyPassword =\n        Encr.decryptPasswordOptionallyEncrypted( XMLHandler.getTagValue( entrynode, \"socksproxy_password\" ) );\n\n    } catch ( KettleXMLException xe ) {\n      throw new KettleXMLException( \"Unable to load job entry of type 'ftp' from XML node\", xe );\n    }\n  }\n\n  public void loadRep( Repository rep, IMetaStore metaStore, ObjectId id_jobentry, List<DatabaseMeta> databases,\n    List<SlaveServer> slaveServers ) throws KettleException {\n    try {\n      protocol = rep.getJobEntryAttributeString( id_jobentry, \"protocol\" );\n      port = rep.getJobEntryAttributeString( id_jobentry, \"port\" );\n      serverName = rep.getJobEntryAttributeString( id_jobentry, \"servername\" );\n      userName = rep.getJobEntryAttributeString( id_jobentry, \"username\" );\n      password =\n        Encr.decryptPasswordOptionallyEncrypted( rep.getJobEntryAttributeString( id_jobentry, \"password\" ) );\n      ftpDirectory = rep.getJobEntryAttributeString( id_jobentry, \"ftpdirectory\" );\n      wildcard = rep.getJobEntryAttributeString( id_jobentry, \"wildcard\" );\n      timeout = rep.getJobEntryAttributeString( id_jobentry, \"timeout\" );\n      activeConnection = rep.getJobEntryAttributeBoolean( id_jobentry, \"active\" );\n\n      copyprevious = rep.getJobEntryAttributeBoolean( id_jobentry, \"copyprevious\" );","sourceCodeStart":306,"sourceCodeEnd":342,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/ftp-delete/impl/src/main/java/org/pentaho/di/job/entries/ftpdelete/JobEntryFTPDelete.java#L306-L342","documentation":"JobEntryFTPDelete.loadXML parses the job entry's XML node (including encrypted socks proxy password fields) into the entry object. Any KettleXMLException raised while reading tags is rethrown with this message to identify which job entry failed to deserialize.","triggerScenarios":"loadXML(entrynode) encounters malformed/missing XML structure or XMLHandler throws while reading attributes like socksproxy_password, then the catch rethrows as KettleXMLException.","commonSituations":"Hand-edited or truncated .kjb files; XML saved by a newer Pentaho version containing unreadable nodes; corrupted repository exports; wrong node passed to loadXML.","solutions":["Open the .kjb in a text editor and validate the <entry> XML structure","Recreate the FTP-delete job entry in Spoon and re-save the job","Check the wrapped `xe` cause to find the exact tag that failed","Upgrade/align the Pentaho version if the XML was written by a newer release"],"exampleFix":"// before\nString pw = Encr.decryptPasswordOptionallyEncrypted(\n  XMLHandler.getTagValue( entrynode, \"socksproxy_password\" ) );\n// after\nString pwTag = XMLHandler.getTagValue( entrynode, \"socksproxy_password\" );\nString pw = pwTag == null ? null\n  : Encr.decryptPasswordOptionallyEncrypted( pwTag );","handlingStrategy":"try-catch","validationCode":"Document doc = XMLHandler.loadXMLFile( jobFile );\nNode entry = XMLHandler.getSubNode( doc, \"entry\" );\nif ( entry == null || XMLHandler.getTagValue( entry, \"type\" ) == null ) {\n  throw new KettleXMLException( \"Entry node missing or type tag absent\" );\n}","typeGuard":null,"tryCatchPattern":"try { jobEntry.loadXML( entrynode, databases, metaStore ); }\ncatch ( KettleXMLException xe ) {\n  log.error( \"FTP-delete entry XML is malformed; cause=\" + xe.getCause() );\n  // recreate the entry rather than retrying the parse\n}","preventionTips":["Avoid hand-editing .kjb files","Keep Pentaho versions consistent across environments","Validate XML against the schema after export/import"],"tags":["xml","job-entry","deserialization","ftp"],"backgroundTag":"schema-validation-failed","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"}