{"record":{"id":"559d888d2e1e8789","repo":"pentaho/pentaho-kettle","slug":"xmlhandler-errorreadingfile","errorCode":"XMLHandler.errorReadingFile","errorMessage":"${XMLHandler.errorReadingFile}","messagePattern":"\\$\\{XMLHandler\\.errorReadingFile\\}","errorType":"exception","errorClass":"KettleXMLException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/xml/XMLHandler.java","lineNumber":614,"sourceCode":"        retries = 0;\n      }\n      int attempts = 0;\n      while ( attempts <= retries ) {\n        try {\n          return loadXMLFile( KettleVFS.getInputStream( fileObject ), systemID, ignoreEntities, namespaceAware );\n        } catch ( Exception ex ) {\n          lastException = ex;\n          try {\n            java.lang.Thread.sleep( 1000 );\n          } catch ( InterruptedException e ) {\n            //Sonar squid S2142 requires the handling of the InterruptedException instead of ignoring it\n            Thread.currentThread().interrupt();\n          }\n        }\n        attempts++;\n      }\n\n      throw new KettleXMLException( BaseMessages.getString(\n        PKG, \"XMLHandler.errorReadingFile\", fileObject.toString() ), lastException );\n    }\n\n    throw new KettleXMLException( BaseMessages.getString(\n      PKG, \"XMLHandler.FileDoesNotExists\", fileObject.toString() ) );\n  }\n\n  /**\n   * Read in an XML file from the passed input stream and return an XML document\n   *\n   * @param inputStream The filename input stream to read the document from\n   * @return the Document if all went well, null if an error occurred!\n   */\n  public static Document loadXMLFile( InputStream inputStream ) throws KettleXMLException {\n    return loadXMLFile( inputStream, null, false, false );\n  }\n\n  /**","sourceCodeStart":596,"sourceCodeEnd":632,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/xml/XMLHandler.java#L596-L632","documentation":"XMLHandler.loadXMLFile() retries reading/parsing a file a few times (with a sleep between attempts) and, when all attempts fail with an exception, throws a KettleXMLException with message key 'XMLHandler.errorReadingFile' including the file path, wrapping the last exception.","triggerScenarios":"Calling any XMLHandler.loadXMLFile(FileObject/… variant) where the file cannot be read or parsed on every attempt — malformed XML, IO errors, encoding problems.","commonSituations":"File locked by another process, incomplete/partial file written by a prior step, invalid XML characters or encoding mismatch, network file system (VFS) latency causing reads to fail within the retry window.","solutions":["Open and parse the file independently (e.g. with xmllint or a DocumentBuilder) to see the underlying 'lastException' cause","Ensure the producing step has finished flushing/closing the file before it is read","Validate the XML is well-formed and its declared encoding matches the bytes","Increase availability of the file (local disk vs flaky network mount) or add your own retry with longer backoff","Catch KettleXMLException and log the file path plus cause for diagnosis"],"exampleFix":"// before\nDocument doc = XMLHandler.loadXMLFile( fileObject );\n// after\nDocument doc;\ntry {\n  doc = XMLHandler.loadXMLFile( fileObject );\n} catch ( KettleXMLException e ) {\n  throw new KettleException( \"Failed to read XML file \" + fileObject.getName().getURI()\n    + \" after retries: \" + e.getMessage(), e );\n}","handlingStrategy":"try-catch","validationCode":"// Pre-validate before calling loadXMLFile\nif ( fileObject == null || !fileObject.exists() ) {\n  throw new KettleException( \"XML file missing: \" + ( fileObject == null ? \"null\" : fileObject.toString() ) );\n}\n// optionally: bytes readable and non-empty\nContent c = fileObject.getContent();\nif ( c.getSize() == 0 ) { throw new KettleException( \"XML file is empty\" ); }","typeGuard":null,"tryCatchPattern":"try {\n  Document doc = XMLHandler.loadXMLFile( fileObject );\n} catch ( KettleXMLException e ) {\n  // message starts with resolved 'XMLHandler.errorReadingFile'; e.getCause() is lastException\n  Throwable cause = e.getCause();\n  throw new KettleException( \"Cannot read \" + fileObject + \": \" + ( cause == null ? e.getMessage() : cause.getMessage() ), e );\n}","preventionTips":["Ensure writers close/flush XML files before downstream reads","Validate XML well-formedness in the producing step","Avoid reading from flaky network shares without your own retry/backoff","Check file encoding matches the XML declaration"],"tags":["xml","file-io","retry","parsing"],"backgroundTag":"file-read-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"}