{"record":{"id":"103ae2f9a673862a","repo":"hashicorp/nomad","slug":"error-reading-symlink-v","errorCode":null,"errorMessage":"error reading symlink: %v","messagePattern":"error reading symlink: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/allocdir/alloc_dir.go","lineNumber":225,"sourceCode":"\ttw := tar.NewWriter(w)\n\tdefer tw.Close()\n\n\twalkFn := func(path string, fileInfo os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Include the path of the file name relative to the alloc dir\n\t\t// so that we can put the files in the right directories\n\t\trelPath, err := filepath.Rel(a.AllocDir, path)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tlink := \"\"\n\t\tif fileInfo.Mode()&os.ModeSymlink != 0 {\n\t\t\ttarget, err := os.Readlink(path)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error reading symlink: %v\", err)\n\t\t\t}\n\t\t\tlink = target\n\t\t}\n\t\thdr, err := tar.FileInfoHeader(fileInfo, link)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error creating file header: %w\", err)\n\t\t}\n\t\thdr.Name = relPath\n\t\tif err := tw.WriteHeader(hdr); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// If it's a directory or symlink we just write the header into the tar\n\t\tif fileInfo.IsDir() || (fileInfo.Mode()&os.ModeSymlink != 0) {\n\t\t\treturn nil\n\t\t}\n\n\t\t// Write the file into the archive","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/allocdir/alloc_dir.go#L207-L243","documentation":"While building a tar snapshot of the allocation directory, AllocDir walks files and, for symlinks, calls os.Readlink to record the link target. If Readlink fails (the entry disappeared mid-walk or the path is not actually a symlink despite the mode bit), the walk is aborted with this wrapped error. It usually indicates a filesystem race or permission problem.","triggerScenarios":"A file that appeared as a symlink in the mode bits was deleted or replaced between the lstat and Readlink calls; permissions deny reading the link; reading a special filesystem where mode bits mislead.","commonSituations":"Snapshotting an alloc dir while a task is actively creating/removing symlinks (temp files, socket links); NFS/network filesystems with unstable entries; containers modifying the shared dir during snapshot.","solutions":["Retry the snapshot; transient races usually clear","Quiesce the task / stop writes to the alloc dir before snapshotting","Check filesystem permissions on the symlink path","Exclude volatile paths from the snapshot"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := allocDir.Snapshot(w)\nif err != nil && strings.Contains(err.Error(), \"error reading symlink\") {\n  // transient race: retry snapshot after quiescing the task\n}","preventionTips":["Quiesce tasks before snapshotting alloc dirs","Avoid snapshotting across unstable network filesystems","Exclude volatile temp paths from snapshots"],"tags":["filesystem","symlink","tar","race-condition"],"backgroundTag":"symlink-read-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"}