{"record":{"id":"4413cafb34842477","repo":"pentaho/pentaho-kettle","slug":"unable-to-read-file-kettle-variables-file","errorCode":null,"errorMessage":"Unable to read file '<KETTLE_VARIABLES_FILE>'","messagePattern":"Unable to read file '<KETTLE_VARIABLES_FILE>'","errorType":"exception","errorClass":"KettleException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/core/KettleVariablesList.java","lineNumber":79,"sourceCode":"        inputStream = variablesList.getClass().getResourceAsStream( \"/\" + Const.KETTLE_VARIABLES_FILE );\n      }\n      if ( inputStream == null ) {\n        throw new KettlePluginException( \"Unable to find standard kettle variables definition file: \" + Const.KETTLE_VARIABLES_FILE );\n      }\n      Document doc = XMLHandler.loadXMLFile( inputStream, null, false, false );\n      Node varsNode = XMLHandler.getSubNode( doc, \"kettle-variables\" );\n      int nrVars = XMLHandler.countNodes( varsNode, \"kettle-variable\" );\n      for ( int i = 0; i < nrVars; i++ ) {\n        Node varNode = XMLHandler.getSubNodeByNr( varsNode, \"kettle-variable\", i );\n        String description = XMLHandler.getTagValue( varNode, \"description\" );\n        String variable = XMLHandler.getTagValue( varNode, \"variable\" );\n        String defaultValue = XMLHandler.getTagValue( varNode, \"default-value\" );\n\n        variablesList.getDescriptionMap().put( variable, description );\n        variablesList.getDefaultValueMap().put( variable, defaultValue );\n      }\n    } catch ( Exception e ) {\n      throw new KettleException( \"Unable to read file '\" + Const.KETTLE_VARIABLES_FILE + \"'\", e );\n    } finally {\n      if ( inputStream != null ) {\n        try {\n          inputStream.close();\n        } catch ( IOException e ) {\n          // we do not able to close property file will log it\n          logger.logDetailed( \"Unable to close file kettle variables definition file\", e );\n        }\n      }\n    }\n  }\n\n  /**\n   * @return A mapping between the name of a standard kettle variable and its description.\n   */\n  public Map<String, String> getDescriptionMap() {\n    return descriptionMap;\n  }","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/core/KettleVariablesList.java#L61-L97","documentation":"After locating kettleVariables.xml, KettleVariablesList.init() parses it with XMLHandler; any exception during reading/parsing is wrapped in a KettleException 'Unable to read file ...'. Unlike error 631 the resource was found but its content could not be read or parsed.","triggerScenarios":"XMLHandler.loadXMLFile(inputStream,...) or the per-variable getTagValue calls throw during KettleVariablesList.init() — malformed XML, closed/IO-failing stream, unexpected DOM structure.","commonSituations":"A corrupted or truncated kettleVariables.xml in a custom build; the wrong file is first on the classpath (e.g. an old version); encoding issues; the stream was already consumed by a previous init attempt.","solutions":["Open kettleVariables.xml on the classpath and validate it is well-formed XML with <kettle-variables>/<kettle-variable> nodes.","Check e.getCause() to distinguish IO failure from parse failure.","Replace the corrupted file with one from a pristine kettle-engine artifact of the matching version.","Ensure init() is only called once and no other code consumed the same InputStream first."],"exampleFix":"// before\nKettleVariablesList.init(); // KettleException on bad XML\n// after\ntry (InputStream in = KettleVariablesList.class.getResourceAsStream(\"/\" + Const.KETTLE_VARIABLES_FILE)) {\n  Document doc = XMLHandler.loadXMLFile(in, null, false, false); // pre-validate structure\n} catch (Exception e) {\n  throw new RuntimeException(\"kettleVariables.xml is corrupt: \" + e.getMessage(), e);\n}\nKettleVariablesList.init();","handlingStrategy":"try-catch","validationCode":"try (InputStream in = getClass().getResourceAsStream(\"/\" + Const.KETTLE_VARIABLES_FILE)) {\n  Document doc = XMLHandler.loadXMLFile(in, null, false, false);\n  if (XMLHandler.getSubNode(doc, \"kettle-variables\") == null) throw new IllegalStateException(\"bad kettleVariables.xml\");\n}","typeGuard":null,"tryCatchPattern":"try { KettleVariablesList.init(); } catch (KettleException e) { throw new RuntimeException(\"kettleVariables.xml unreadable: \" + e.getCause(), e); }","preventionTips":["Validate the XML with a parser/linter before shipping custom builds","Never share one InputStream across multiple init calls","Keep the resource file byte-identical to the official distribution"],"tags":["xml","parse-error","configuration"],"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"}