{"record":{"id":"906a10fd285a2603","repo":"hashicorp/nomad","slug":"error-writing-to-file-q-w","errorCode":null,"errorMessage":"error writing to file %q: %w","messagePattern":"error writing to file %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocwatcher/alloc_watcher.go","lineNumber":677,"sourceCode":"\t\t\t\treturn fmt.Errorf(\"error chmoding file %w\", err)\n\t\t\t}\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 := f.Chown(hdr.Uid, hdr.Gid); err != nil {\n\t\t\t\t\tf.Close()\n\t\t\t\t\treturn fmt.Errorf(\"error chowning file %w\", err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// We write in chunks so that we can test if the client\n\t\t\t// is still alive\n\t\t\tfor !canceled() {\n\t\t\t\tn, err := tr.Read(buf)\n\t\t\t\tif n > 0 && (err == nil || err == io.EOF) {\n\t\t\t\t\tif _, err := f.Write(buf[:n]); err != nil {\n\t\t\t\t\t\tf.Close()\n\t\t\t\t\t\treturn fmt.Errorf(\"error writing to file %q: %w\", f.Name(), err)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.Close()\n\t\t\t\t\tif err != io.EOF {\n\t\t\t\t\t\treturn fmt.Errorf(\"error reading snapshot: %w\", err)\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\n\tif canceled() {\n\t\treturn ctx.Err()\n\t}","sourceCodeStart":659,"sourceCodeEnd":695,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocwatcher/alloc_watcher.go#L659-L695","documentation":"streamAllocDir copies files from a previous allocation's data directory (snapshot tar stream read via a tar.Reader) into the new allocation's directory. This error wraps any failure from f.Write while extracting the tar entry, and includes the destination file name and the underlying OS error.","triggerScenarios":"During alloc migration (migrateAllocDir), a tar entry read from the previous allocation's snapshot is written to the new alloc dir and the write fails — typically disk full, permission denied on the destination path, a bad symlink target escaping the alloc dir, or the destination file being closed/unwritable.","commonSituations":"Disk quota or out-of-space on the client's alloc_dir volume; corrupted or malicious symlink entries in a previous alloc's data (the BadSymlink tests exercise exactly this); read-only filesystem; file previously created with restrictive permissions by another user.","solutions":["Check disk space and inode availability on the client's alloc_dir volume (df -h / df -i).","Inspect the destination file path and its permissions/ownership; ensure the nomad user can write to alloc_dir.","Verify no symlinks in the previous alloc's data escape the alloc directory (Nomad rejects these); clean up the old alloc dir.","Retry the allocation migration after freeing space or fixing permissions; a failed migration will be rescheduled."],"exampleFix":"// before (server-side fix is not possible; caller-side remedy)\n// client hits: error writing to file \"/data/alloc/.../app.log\": write ...: no space left on device\n// after\n$ df -h /data/alloc  # free space or expand volume, then restart the failed allocation","handlingStrategy":"validation","validationCode":"// before enabling alloc migration on a client, precheck the target volume\nif err := checkWritable(conf.AllocDir); err != nil {\n    return fmt.Errorf(\"alloc dir not writable, migration would fail: %w\", err)\n}\nfunc checkWritable(dir string) error {\n    probe := filepath.Join(dir, \".nomad-write-probe\")\n    if err := os.WriteFile(probe, []byte(\"ok\"), 0o600); err != nil { return err }\n    return os.Remove(probe)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Monitor disk usage on alloc_dir volumes and alert before they fill","Ensure consistent ownership/permissions of alloc_dir across node maintenance","Audit old alloc dirs for symlinks that could escape and block migration","Keep Nomad updated: symlink-escape protections and stream handling have been patched over releases"],"tags":["filesystem","io","alloc-migration"],"backgroundTag":"file-write-failed","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"}