{"record":{"id":"e303ba85bcbff4fa","repo":"apache/hadoop","slug":"a-valid-owner-or-group-must-be-specified","errorCode":null,"errorMessage":"A valid owner or group must be specified.","messagePattern":"A valid owner or group must be specified\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/AzureBlobFileSystem.java","lineNumber":1098,"sourceCode":"   * @param owner If it is null, the original username remains unchanged.\n   * @param group If it is null, the original groupname remains unchanged.\n   */\n  @Override\n  public void setOwner(final Path path, final String owner, final String group)\n      throws IOException {\n    LOG.debug(\n        \"AzureBlobFileSystem.setOwner path: {}\", path);\n    TracingContext tracingContext = new TracingContext(clientCorrelationId,\n        fileSystemId, FSOperationType.SET_OWNER, true, tracingHeaderFormat,\n        listener);\n\n    if (!getIsNamespaceEnabled(tracingContext)) {\n      super.setOwner(path, owner, group);\n      return;\n    }\n\n    if ((owner == null || owner.isEmpty()) && (group == null || group.isEmpty())) {\n      throw new IllegalArgumentException(\"A valid owner or group must be specified.\");\n    }\n\n    Path qualifiedPath = makeQualified(path);\n\n    try {\n      getAbfsStore().setOwner(qualifiedPath,\n          owner,\n          group,\n          tracingContext);\n    } catch (AzureBlobFileSystemException ex) {\n      checkException(path, ex);\n    }\n  }\n\n  /**\n   * Set the value of an attribute for a non-root path.\n   *\n   * @param path The path on which to set the attribute","sourceCodeStart":1080,"sourceCodeEnd":1116,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/AzureBlobFileSystem.java#L1080-L1116","documentation":"Thrown by AzureBlobFileSystem.setOwner when both the owner and group arguments are null or empty on a hierarchical-namespace (HNS) enabled storage account. Hadoop's contract requires at least one of owner/group to change, and ABFS enforces this before issuing the backend SetAccessControl call. On non-HNS accounts the call instead delegates to the superclass implementation and never reaches this check.","triggerScenarios":"Calling fs.setOwner(path, null, null), fs.setOwner(path, \"\", \"\"), or any combination where owner and group are both null/empty, on an account where getIsNamespaceEnabled() is true.","commonSituations":"Generic tooling (distcp -p, chown wrappers, Spark/Hadoop commit protocols) forwarding unset owner/group fields; caller reading FileStatus and re-passing nulls; code ported from filesystems that tolerate no-op setOwner calls.","solutions":["Pass a non-empty owner or a non-empty group (at least one must change).","For a no-op, read current values via getFileStatus(path) and re-pass them.","Guard callers to skip the setOwner call entirely when both fields are null/empty."],"exampleFix":"// before\nfs.setOwner(path, null, null);\n\n// after\nFileStatus st = fs.getFileStatus(path);\nfs.setOwner(path, st.getOwner(), null); // change owner, keep group","handlingStrategy":"validation","validationCode":"boolean hasOwner = owner != null && !owner.isEmpty();\nboolean hasGroup = group != null && !group.isEmpty();\nif (!hasOwner && !hasGroup) {\n  return; // nothing to change; skip instead of calling setOwner\n}\nfs.setOwner(path, owner, group);","typeGuard":"static boolean hasText(String s) {\n  return s != null && !s.isEmpty();\n}","tryCatchPattern":"try {\n  fs.setOwner(path, owner, group);\n} catch (IllegalArgumentException e) {\n  // caller bug: fix the arguments, do not retry\n  throw new IllegalArgumentException(\"setOwner requires owner or group for \" + path, e);\n}","preventionTips":["Never forward nullable owner/group from configs or FileStatus without null/empty checks.","Treat both-empty as a skip, not a call.","Wrap chown-style helpers with a single validation utility reused across owner/group/permission setters."],"tags":["azure-abfs","setowner","illegal-argument","hns","acl"],"backgroundTag":"missing-required-argument","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}