{"record":{"id":"8441668d92e16f23","repo":"hashicorp/nomad","slug":"error-chowning-directory-w","errorCode":null,"errorMessage":"error chowning directory %w","messagePattern":"error chowning directory %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocwatcher/alloc_watcher.go","lineNumber":622,"sourceCode":"\t\t\t// the message out of the file and return it.\n\t\t\terrBuf := make([]byte, int(hdr.Size))\n\t\t\tif _, err := tr.Read(errBuf); err != nil && err != io.EOF {\n\t\t\t\treturn fmt.Errorf(\"error streaming previous alloc %q for new alloc %q; failed reading error message: %w\",\n\t\t\t\t\tp.prevAllocID, p.allocID, err)\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"error streaming previous alloc %q for new alloc %q: %s\",\n\t\t\t\tp.prevAllocID, p.allocID, string(errBuf))\n\t\t}\n\n\t\t// If the header is for a directory we create the directory\n\t\tif hdr.Typeflag == tar.TypeDir {\n\t\t\tname := filepath.Join(dest, hdr.Name)\n\t\t\tos.MkdirAll(name, os.FileMode(hdr.Mode))\n\n\t\t\t// Can't change owner if not root or on Windows.\n\t\t\tif euid == 0 {\n\t\t\t\tif err := os.Chown(name, hdr.Uid, hdr.Gid); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"error chowning directory %w\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\t// If the header is for a symlink we create the symlink\n\t\tif hdr.Typeflag == tar.TypeSymlink {\n\t\t\tif err = os.Symlink(hdr.Linkname, filepath.Join(dest, hdr.Name)); err != nil {\n\t\t\t\treturn fmt.Errorf(\"error creating symlink: %w\", err)\n\t\t\t}\n\n\t\t\tfor _, path := range []string{hdr.Name, hdr.Linkname} {\n\t\t\t\tif escapes, err := escapingfs.PathEscapesAllocDir(dest, \"\", path); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"error evaluating symlink: %w\", err)\n\t\t\t\t} else if escapes {\n\t\t\t\t\treturn fmt.Errorf(\"archive contains symlink that escapes alloc dir\")\n\t\t\t\t}\n\t\t\t}\n","sourceCodeStart":604,"sourceCodeEnd":640,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocwatcher/alloc_watcher.go#L604-L640","documentation":"While extracting a directory entry from the alloc dir tar archive, Nomad creates the directory then attempts os.Chown with the Uid/Gid from the tar header. This error is returned when the chown fails — only attempted when running as euid 0 (root) on non-Windows.","triggerScenarios":"Running as root, streamAllocDir processes a tar.TypeDir header, MkdirAll succeeds, but os.Chown on the new directory fails (e.g. Uid/Gid not valid on the host, filesystem does not support chown).","commonSituations":"Migration across nodes with mismatched UID/GID ranges; containerized root lacking CAP_CHOWN; network filesystems (NFS with root squashing) rejecting chown.","solutions":["Ensure the filesystem backing the data dir supports chown (avoid root-squashed NFS)","Grant the Nomad client CAP_CHOWN if running in a container as root","Verify the tar header Uid/Gid values are valid on the destination host","Run the client as a non-root user to skip chown, if ownership does not matter"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Confirm the destination filesystem supports chown and the client has the capability:\n// touch a test file and os.Chown it with the expected uid/gid before starting the client","typeGuard":null,"tryCatchPattern":"if err := watcher.Wait(ctx); err != nil {\n    var pathErr *os.PathError\n    if errors.As(err, &pathErr) && errors.Is(pathErr.Err, syscall.EPERM) {\n        // fall back: run client without chown or fix capabilities\n    }\n    return err\n}","preventionTips":["Use local POSIX filesystems (ext4/xfs) for the client data dir","Grant CAP_CHOWN when running the client in containers as root","Keep consistent UID/GID ranges across the cluster"],"tags":["nomad","filesystem","permissions","chown"],"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"}