{"record":{"id":"aa5c63c73f322813","repo":"pentaho/pentaho-kettle","slug":"unable-to-load-job-entry-of-type-sftp-from-xml-node","errorCode":null,"errorMessage":"Unable to load job entry of type 'SFTP' from XML node","messagePattern":"Unable to load job entry of type 'SFTP' from XML node","errorType":"exception","errorClass":"KettleXMLException","httpStatus":null,"severity":"error","filePath":"plugins/get-file-sftp/impl/src/main/java/org/pentaho/di/job/entries/sftp/JobEntrySFTP.java","lineNumber":196,"sourceCode":"        isaddresult = \"Y\".equalsIgnoreCase( addresult );\n      }\n\n      createtargetfolder = \"Y\".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, \"createtargetfolder\" ) );\n      copyprevious = \"Y\".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, \"copyprevious\" ) );\n\n      usekeyfilename = \"Y\".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, \"usekeyfilename\" ) );\n      keyfilename = XMLHandler.getTagValue( entrynode, \"keyfilename\" );\n      keyfilepass = Encr.decryptPasswordOptionallyEncrypted( XMLHandler.getTagValue( entrynode, \"keyfilepass\" ) );\n      compression = XMLHandler.getTagValue( entrynode, \"compression\" );\n\n      proxyType = XMLHandler.getTagValue( entrynode, \"proxyType\" );\n      proxyHost = XMLHandler.getTagValue( entrynode, \"proxyHost\" );\n      proxyPort = XMLHandler.getTagValue( entrynode, \"proxyPort\" );\n      proxyUsername = XMLHandler.getTagValue( entrynode, \"proxyUsername\" );\n      proxyPassword =\n        Encr.decryptPasswordOptionallyEncrypted( XMLHandler.getTagValue( entrynode, \"proxyPassword\" ) );\n    } catch ( KettleXMLException xe ) {\n      throw new KettleXMLException( \"Unable to load job entry of type 'SFTP' 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      serverName = rep.getJobEntryAttributeString( id_jobentry, \"servername\" );\n      serverPort = rep.getJobEntryAttributeString( id_jobentry, \"serverport\" );\n\n      userName = rep.getJobEntryAttributeString( id_jobentry, \"username\" );\n      password =\n        Encr.decryptPasswordOptionallyEncrypted( rep.getJobEntryAttributeString( id_jobentry, \"password\" ) );\n\n      sftpDirectory = rep.getJobEntryAttributeString( id_jobentry, \"sftpdirectory\" );\n      targetDirectory = rep.getJobEntryAttributeString( id_jobentry, \"targetdirectory\" );\n      wildcard = rep.getJobEntryAttributeString( id_jobentry, \"wildcard\" );\n      remove = rep.getJobEntryAttributeBoolean( id_jobentry, \"remove\" );\n","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/get-file-sftp/impl/src/main/java/org/pentaho/di/job/entries/sftp/JobEntrySFTP.java#L178-L214","documentation":"JobEntrySFTP.loadXML() wraps any KettleXMLException raised while reading the SFTP job entry's XML attributes (including the optional proxy settings) into a new KettleXMLException with the literal message \"Unable to load job entry of type 'SFTP' from XML node\". It means the <entry type='SFTP'> element in the .kjb file could not be deserialized; the original parse error is attached as cause.","triggerScenarios":"Loading a job XML where an SFTP entry element is malformed or contains tags XMLHandler cannot parse — e.g., hand-edited XML, wrong nesting, or an attribute structure from a different plugin version — inside the try block covering getTagValue calls and password decryption.","commonSituations":"Manually editing .kjb files; generating job XML programmatically with wrong tag names; version migration where the SFTP entry schema changed; truncated/corrupted job files.","solutions":["Inspect getCause() to identify the exact tag that failed to parse and correct it in the .kjb file.","Reopen and re-save the SFTP job entry in Spoon to regenerate valid XML.","Compare the entry XML against a working SFTP entry saved by the same Kettle version and fix tag names/nesting.","Confirm the get-file-sftp plugin version matches the Pentaho version loading the job."],"exampleFix":"<!-- before: misspelled/nested tag -->\n<proxyPasword>secret</proxyPasword>\n<!-- after -->\n<proxyPassword>secret</proxyPassword>","handlingStrategy":"try-catch","validationCode":"// sanity-check the SFTP entry XML node before loadXML\nif ( !\"SFTP\".equals( XMLHandler.getTagValue( entrynode, \"type\" ) ) && entrynode.getAttributes() == null ) {\n  throw new IllegalArgumentException( \"Node is not a valid SFTP job entry\" );\n}","typeGuard":null,"tryCatchPattern":"try {\n  entry.loadXML( entrynode, databases, metaStore );\n} catch ( KettleXMLException e ) {\n  log.error( \"SFTP entry XML load failed: \" + e.getCause() );\n  throw new KettleException( \"Correct the SFTP entry XML in the .kjb file and reload\", e );\n}","preventionTips":["Edit SFTP entries via Spoon instead of editing XML directly.","Validate .kjb files after scripted generation or migration.","Keep the get-file-sftp plugin at the same version as the Pentaho server.","Diff suspect entry XML against a known-good entry saved by the same version."],"tags":["kettle","sftp","xml","deserialization"],"backgroundTag":"xml-unmarshal-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"}