{"record":{"id":"53a9f67bb78470d8","repo":"nodejs/node","slug":"setting-group-failed-for-s-s-n","errorCode":null,"errorMessage":"setting group failed for [%s]: %s\\n","messagePattern":"setting group failed for \\[(.+?)\\]: (.+?)\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"deps/brotli/c/tools/brotli.c","lineNumber":872,"sourceCode":"   fully featured implementation is way too hacky; add more hacks by request. */\nstatic void CopyStat(const char* input_path, const char* output_path) {\n  struct stat statbuf;\n  int res;\n  if (input_path == 0 || output_path == 0) {\n    return;\n  }\n  if (stat(input_path, &statbuf) != 0) {\n    return;\n  }\n  res = CopyTimeStat(&statbuf, output_path);\n  res = chmod(output_path, statbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));\n  if (res != 0) {\n    fprintf(stderr, \"setting access bits failed for [%s]: %s\\n\",\n            PrintablePath(output_path), strerror(errno));\n  }\n  res = chown(output_path, (uid_t)-1, statbuf.st_gid);\n  if (res != 0) {\n    fprintf(stderr, \"setting group failed for [%s]: %s\\n\",\n            PrintablePath(output_path), strerror(errno));\n  }\n  res = chown(output_path, statbuf.st_uid, (gid_t)-1);\n  if (res != 0) {\n    fprintf(stderr, \"setting user failed for [%s]: %s\\n\",\n            PrintablePath(output_path), strerror(errno));\n  }\n}\n\n/* Result ownership is passed to caller.\n   |*dictionary_size| is set to resulting buffer size. */\nstatic BROTLI_BOOL ReadDictionary(Context* context, Command command) {\n  static const int kMaxDictionarySize =\n      BROTLI_MAX_DISTANCE - BROTLI_MAX_BACKWARD_LIMIT(24);\n  FILE* f;\n  int64_t file_size_64;\n  uint8_t* buffer;\n  size_t bytes_read;","sourceCodeStart":854,"sourceCodeEnd":890,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/brotli/c/tools/brotli.c#L854-L890","documentation":"During `CopyStat`, `chown()` failed when trying to set the group ID of the output file to match the input (uid left at -1, so only the group changes). Like the chmod failure, this is non-fatal — the data operation already succeeded. Only the metadata copy reported an error.","triggerScenarios":"The invoking user is not a member of the target group (EPERM); running as non-root and the output is on a filesystem that requires root for chown; NFS with root-squash; the output was deleted before chown ran.","commonSituations":"Compressing files owned by another user/group and the caller lacks privileges to set that group on the new output file; cross-user batch processing.","solutions":["Run as root or as a user who is a member of the target group.","Use `--no-copy-stat` to skip metadata replication entirely.","Accept the warning if the group ownership of the output does not matter for your use case."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"#include <unistd.h>\n#include <grp.h>\n#include <stdbool.h>\n\nbool can_set_group(gid_t target_gid) {\n    if (geteuid() == 0) return true; // root can set any group\n    // Non-root: must be a member of the target group\n    int n = getgroups(0, NULL);\n    if (n <= 0) return false;\n    gid_t *groups = malloc(n * sizeof(gid_t));\n    getgroups(n, groups);\n    bool ok = false;\n    for (int i = 0; i < n; i++) {\n        if (groups[i] == target_gid) { ok = true; break; }\n    }\n    free(groups);\n    return ok;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run as root or ensure the user is in the target group before batch compression.","Use `--no-copy-stat` when group preservation is not required.","Accept the warning as non-fatal; data integrity is unaffected."],"tags":["filesystem","metadata","permissions","brotli"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}