{"record":{"id":"3d619106c080f2e0","repo":"apache/hadoop","slug":"path-is-a-directory-3d6191","errorCode":null,"errorMessage":"<path> is a directory","messagePattern":"<path> is a directory","errorType":"exception","errorClass":"FileAlreadyExistsException","httpStatus":null,"severity":"error","filePath":"hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3AFileSystem.java","lineNumber":2168,"sourceCode":"    }\n\n    // list logic\n    boolean skipList = createPerf || magic || cCreate || cEtag;\n    if (skipList) {\n      probes.remove(StatusProbeEnum.List);\n    }\n\n    // if probes are required -request them and evaluate the result.\n    if (!probes.isEmpty()) {\n      try {\n\n        // get the status or throw an FNFE.\n        FileStatus status = innerGetFileStatus(path, false, probes);\n\n        // if the thread reaches here, there is something at the path\n        if (status.isDirectory()) {\n          // path references a directory: automatic error\n          throw new FileAlreadyExistsException(path + \" is a directory\");\n        }\n        if (!overwrite) {\n          // path references a file and overwrite is disabled\n          throw new FileAlreadyExistsException(path + \" already exists\");\n        }\n        LOG.debug(\"Overwriting file {}\", path);\n      } catch (FileNotFoundException e) {\n        // this means there is nothing at the path; all good.\n      }\n    } else {\n      LOG.debug(\"Skipping all probes with flags:\"\n              + \" createPerf={}, magic={}, ccAvailable={}, cCreate={}, cEtag={}\",\n          createPerf, magic, ccAvailable, cCreate, cEtag);\n    }\n    instrumentation.fileCreated();\n    final BlockOutputStreamStatistics outputStreamStatistics\n        = statisticsContext.newOutputStreamStatistics();\n    PutTracker putTracker =","sourceCodeStart":2150,"sourceCodeEnd":2186,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3AFileSystem.java#L2150-L2186","documentation":"Before writing, create() runs the configured probes (LIST + HEAD via innerGetFileStatus); if the path resolves and the entry is a directory, FileAlreadyExistsException '<path> is a directory' is thrown regardless of the overwrite flag - the source marks it 'automatic error'. S3A never replaces a directory (marker or parent of children) with a file, mirroring POSIX create(2) EISDIR.","triggerScenarios":"fs.create(path) where path is currently a directory, with or without children; overwrite=true does not change the outcome; createPerf/magic paths still hit the probe result when the directory is found.","commonSituations":"Output file name collides with an existing partition directory (e.g. writing 'data' when 'data/' exists); reruns of a pipeline that previously materialized a directory at the same path; path normalization or trailing-slash differences making a file target resolve to a directory.","solutions":["Choose a different target name for the file so it does not collide with the directory","Delete or move the existing directory first: fs.delete(dir, true)","Check fs.getFileStatus(path).isDirectory() before create and fail with a clear message"],"exampleFix":"// before\nFSDataOutputStream out = fs.create(new Path(base, name));\n\n// after\nPath target = new Path(base, name);\nif (fs.exists(target) && fs.getFileStatus(target).isDirectory()) {\n  throw new IllegalArgumentException(target + \" is a directory; refusing to replace it\");\n}\nFSDataOutputStream out = fs.create(target, true);","handlingStrategy":"validation","validationCode":"static boolean targetIsDirectory(FileSystem fs, Path p) throws IOException {\n  return fs.exists(p) && fs.getFileStatus(p).isDirectory();\n}","typeGuard":null,"tryCatchPattern":"Catch FileAlreadyExistsException around create() and branch on 'is a directory' in the message: directory collisions are structural (rename/delete or pick a new name), while plain 'already exists' is an overwrite-flag decision.","preventionTips":["Check getFileStatus(path).isDirectory() before create in generic write helpers","Keep file and partition layouts disjoint in output schemas","Clean or version output paths between pipeline runs"],"tags":["s3a","create","file-already-exists","directory"],"backgroundTag":"file-already-exists","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}