{"record":{"id":"df8d26413b3e4593","repo":"apache/hadoop","slug":"owner-for-path-did-not-match-expected-owne","errorCode":null,"errorMessage":"Owner '{}' for path {} did not match expected owner '{}'","messagePattern":"Owner '(.+?)' for path (.+?) did not match expected owner '(.+?)'","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/SecureIOUtils.java","lineNumber":299,"sourceCode":"\n  private static void checkStat(File f, String owner, String group, \n      String expectedOwner, \n      String expectedGroup) throws IOException {\n    boolean success = true;\n    if (expectedOwner != null &&\n        !expectedOwner.equals(owner)) {\n      if (Path.WINDOWS) {\n        UserGroupInformation ugi =\n            UserGroupInformation.createRemoteUser(expectedOwner);\n        final String adminsGroupString = \"Administrators\";\n        success = owner.equals(adminsGroupString)\n            && ugi.getGroupsSet().contains(adminsGroupString);\n      } else {\n        success = false;\n      }\n    }\n    if (!success) {\n      throw new IOException(\n          \"Owner '\" + owner + \"' for path \" + f + \" did not match \" +\n              \"expected owner '\" + expectedOwner + \"'\");\n    }\n  }\n\n  /**\n   * Signals that an attempt to create a file at a given pathname has failed\n   * because another file already existed at that path.\n   */\n  public static class AlreadyExistsException extends IOException {\n    private static final long serialVersionUID = 1L;\n\n    public AlreadyExistsException(String msg) {\n      super(msg);\n    }\n\n    public AlreadyExistsException(Throwable cause) {\n      super(cause);","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/SecureIOUtils.java#L281-L317","documentation":"checkFileOwner throws this IOException when the actual owner of a local file differs from the expectedOwner argument passed to SecureIOUtils.openForRead/openForWrite. The check prevents swapped or tampered local files from being trusted. On Windows there is a carve-out: the check passes if the real owner is 'Administrators' and the remote user belongs to the Administrators group; otherwise any mismatch fails.","triggerScenarios":"openForRead(file, expectedOwner) where file's POSIX owner is a different account: local dirs owned by another user, files copied between hosts preserving wrong ownership, or a daemon writing under a different effective user than the job owner.","commonSituations":"Someone ran chown -R over hadoop local/data dirs; jobs submitted as user A while the NodeManager dirs were created by user B; backups restored with altered ownership; NFS mounts with root-squash rewriting owners.","solutions":["Fix ownership: chown expectedOwner:group on the file and its directory","Ensure the job is submitted/run as the user that owns the files (kinit as that user, check proxy user settings)","Delete the offending scratch file so it is regenerated under the right owner","On Windows hosts, run the client under a user in the Administrators group so the special case applies"],"exampleFix":"// before\nFSDataInputStream in = SecureIOUtils.openForRead(f, \"jobuser\"); // owner mismatch IOException\n\n// after\nUserPrincipal owner = Files.getOwner(f.toPath());\nif (!\"jobuser\".equals(owner.getName())) {\n  throw new IOException(f + \" owned by \" + owner.getName() + \"; run: chown jobuser \" + f);\n}\nFSDataInputStream in = SecureIOUtils.openForRead(f, \"jobuser\");","handlingStrategy":"try-catch","validationCode":"String actual = Files.getOwner(f.toPath()).getName();\nif (!expectedOwner.equals(actual)\n    && !(Path.WINDOWS && \"Administrators\".equals(actual)\n        && UserGroupInformation.createRemoteUser(expectedOwner).getGroupsSet().contains(\"Administrators\"))) {\n  throw new IOException(f + \" owned by \" + actual + \", expected \" + expectedOwner);\n}","typeGuard":null,"tryCatchPattern":"try {\n  in = SecureIOUtils.openForRead(f, expectedOwner);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"did not match expected owner\")) {\n    // ownership problem: chown or delete-and-regenerate, then retry\n  } else { throw e; }\n}","preventionTips":["Standardize on one effective user for writing and reading secure local files","Never chown hadoop local/data directories ad hoc; if needed, do it for the whole directory tree consistently","On Windows, ensure the client user is in the Administrators group to hit the allowed special case"],"tags":["hadoop","file-ownership","security","posix"],"backgroundTag":"file-ownership-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}