{"record":{"id":"63fbacf95362c05f","repo":"apache/hadoop","slug":"not-a-file-jsonfile","errorCode":null,"errorMessage":"Not a file: ${jsonFile}","messagePattern":"Not a file: (.+?)","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/JsonSerialization.java","lineNumber":181,"sourceCode":"    return mapper.readValue(stream, classType);\n  }\n\n  /**\n   * Load from a JSON text file.\n   * @param jsonFile input file\n   * @return the parsed JSON\n   * @throws IOException IO problems\n   * @throws JsonParseException If the input is not well-formatted\n   * @throws JsonMappingException failure to map from the JSON to this class\n   */\n  @SuppressWarnings(\"unchecked\")\n  public synchronized T load(File jsonFile)\n      throws IOException, JsonParseException, JsonMappingException {\n    if (!jsonFile.exists()) {\n      throw new FileNotFoundException(\"No such file: \" + jsonFile);\n    }\n    if (!jsonFile.isFile()) {\n      throw new FileNotFoundException(\"Not a file: \" + jsonFile);\n    }\n    if (jsonFile.length() == 0) {\n      throw new EOFException(\"File is empty: \" + jsonFile);\n    }\n    try {\n      return mapper.readValue(jsonFile, classType);\n    } catch (IOException e) {\n      LOG.warn(\"Exception while parsing json file {}\", jsonFile, e);\n      throw e;\n    }\n  }\n\n  /**\n   * Save to a local file. Any existing file is overwritten unless\n   * the OS blocks that.\n   * @param file file\n   * @param instance instance\n   * @throws IOException IO exception","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/JsonSerialization.java#L163-L199","documentation":"load(File) requires a regular file: when the path exists but isFile() is false (a directory, device, or special file) it throws FileNotFoundException(\"Not a file: <path>\"). The guard keeps Jackson from trying to stream a directory, whose error would be far less clear.","triggerScenarios":"Passing a directory to load(): a config property pointing at the directory that contains the JSON instead of the file, or a path built with the filename component dropped.","commonSituations":"Property set to /etc/hadoop/conf while the code expects /etc/hadoop/conf/file.json; glob or variable expansion returning the parent directory; a CLI flag where the user passed the folder.","solutions":["Inspect the path (ls -ld) and correct the property or argument to name the actual JSON file.","Fix path construction so the filename is always appended to the directory component.","Add an isFile() check upstream that raises an error naming the offending setting."],"exampleFix":"// before\nFile f = new File(conf.get(\"metadata.dir\")); // points at the directory\nMyType t = serializer.load(f);\n\n// after\nFile f = new File(conf.get(\"metadata.dir\"), \"metadata.json\");\nreturn serializer.load(f);","handlingStrategy":"validation","validationCode":"if (!f.isFile()) {\n  throw new IllegalArgumentException(\n      \"Configured path is not a regular file: \" + f.getAbsolutePath());\n}\nreturn serializer.load(f);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate user- or config-supplied paths with isFile() before passing them to loaders.","Separate directory and filename config keys so callers cannot conflate them."],"tags":["json","file","hadoop-common","misconfiguration"],"backgroundTag":"path-is-a-directory","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}