{"record":{"id":"dc991d221870d721","repo":"hashicorp/nomad","slug":"couldn-t-change-owner-group-of-v-to-uid-v-gid","errorCode":null,"errorMessage":"Couldn't change owner/group of %v to (uid: %v, gid: %v): %w","messagePattern":"Couldn't change owner/group of (.+?) to \\(uid: (.+?), gid: (.+?)\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocdir/fs_unix.go","lineNumber":62,"sourceCode":"\t}\n\n\tu, err := users.Lookup(\"nobody\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Unable to find nobody user: %w\", err)\n\t}\n\n\tuid, err := getUid(u)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tgid, err := getGid(u)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := os.Chown(path, uid, gid); err != nil {\n\t\treturn fmt.Errorf(\"Couldn't change owner/group of %v to (uid: %v, gid: %v): %w\", path, uid, gid, err)\n\t}\n\n\treturn nil\n}\n\n// getUid for a user\nfunc getUid(u *user.User) (int, error) {\n\tuid, err := strconv.Atoi(u.Uid)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"Unable to convert Uid to an int: %w\", err)\n\t}\n\n\treturn uid, nil\n}\n\n// getGid for a user\nfunc getGid(u *user.User) (int, error) {\n\tgid, err := strconv.Atoi(u.Gid)","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocdir/fs_unix.go#L44-L80","documentation":"The final step of dropDirPermissions is os.Chown(path, uid, gid) to hand the shared directory to the resolved 'nobody' uid/gid. This error wraps the chown failure with the target uid/gid for diagnosis. Even with root privileges, the kernel can refuse the change due to filesystem restrictions or invalid ids.","triggerScenarios":"os.Chown(path, uid, gid) failed after 'nobody' was successfully resolved, during chroot-isolation setup of the shared alloc directory.","commonSituations":"Alloc dir on root-squashed NFS (root mapped to anonymous, chown denied); filesystem mounted with 'nosuid'/read-only or an FS that disallows chown; uid/gid out of range for the filesystem; immutable/append-only attributes.","solutions":["Check the wrapped error for EPERM/EINVAL and inspect the alloc-dir mount type and options (mount | grep alloc).","Avoid root-squashed NFS for data_dir, or adjust the export's anonuid/anongid settings.","Verify the resolved nobody uid/gid (getent passwd nobody) are valid on this filesystem.","Clear immutable attributes (chattr -i) if lsattr shows them on the directory."],"exampleFix":"// before: alloc dir on root-squashed NFS\n/data/nomad  *(rw,sync,root_squash)\n// after: allow root ownership changes\n/data/nomad  *(rw,sync,no_root_squash)","handlingStrategy":"try-catch","validationCode":"// verify chown works on the alloc-dir filesystem before allocations\nprobe := filepath.Join(allocDir, \".chown-probe\")\nos.WriteFile(probe, nil, 0o600)\nerr := os.Chown(probe, nobodyUID, nobodyGID)\nos.Remove(probe) // err must be nil","typeGuard":null,"tryCatchPattern":"if err := td.Build(); err != nil {\n    if strings.Contains(err.Error(), \"Couldn't change owner/group\") {\n        var errno syscall.Errno\n        if errors.As(err, &errno) && errno == syscall.EPERM {\n            log.Printf(\"alloc-dir FS rejects chown; check NFS root_squash / mount opts\")\n        }\n    }\n    return err\n}","preventionTips":["Use local disks or NFS exports without root_squash for data_dir.","Run a chown probe as part of client health checks.","Verify the nobody uid/gid are valid on the target filesystem."],"tags":["filesystem","permissions","chown","linux","nomad"],"backgroundTag":"chown-permission-denied","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}