nodejs/node · warning

setting group failed for [%s]: %s\n

Error message

setting group failed for [%s]: %s\n

What it means

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.

Source

Thrown at deps/brotli/c/tools/brotli.c:872

   fully featured implementation is way too hacky; add more hacks by request. */
static void CopyStat(const char* input_path, const char* output_path) {
  struct stat statbuf;
  int res;
  if (input_path == 0 || output_path == 0) {
    return;
  }
  if (stat(input_path, &statbuf) != 0) {
    return;
  }
  res = CopyTimeStat(&statbuf, output_path);
  res = chmod(output_path, statbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
  if (res != 0) {
    fprintf(stderr, "setting access bits failed for [%s]: %s\n",
            PrintablePath(output_path), strerror(errno));
  }
  res = chown(output_path, (uid_t)-1, statbuf.st_gid);
  if (res != 0) {
    fprintf(stderr, "setting group failed for [%s]: %s\n",
            PrintablePath(output_path), strerror(errno));
  }
  res = chown(output_path, statbuf.st_uid, (gid_t)-1);
  if (res != 0) {
    fprintf(stderr, "setting user failed for [%s]: %s\n",
            PrintablePath(output_path), strerror(errno));
  }
}

/* Result ownership is passed to caller.
   |*dictionary_size| is set to resulting buffer size. */
static BROTLI_BOOL ReadDictionary(Context* context, Command command) {
  static const int kMaxDictionarySize =
      BROTLI_MAX_DISTANCE - BROTLI_MAX_BACKWARD_LIMIT(24);
  FILE* f;
  int64_t file_size_64;
  uint8_t* buffer;
  size_t bytes_read;

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Run as root or as a user who is a member of the target group.
  2. Use `--no-copy-stat` to skip metadata replication entirely.
  3. Accept the warning if the group ownership of the output does not matter for your use case.
Defensive patterns

Strategy: fallback

Validate before calling

#include <unistd.h>
#include <grp.h>
#include <stdbool.h>

bool can_set_group(gid_t target_gid) {
    if (geteuid() == 0) return true; // root can set any group
    // Non-root: must be a member of the target group
    int n = getgroups(0, NULL);
    if (n <= 0) return false;
    gid_t *groups = malloc(n * sizeof(gid_t));
    getgroups(n, groups);
    bool ok = false;
    for (int i = 0; i < n; i++) {
        if (groups[i] == target_gid) { ok = true; break; }
    }
    free(groups);
    return ok;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/53a9f67bb78470d8. Report an issue: GitHub.