{"record":{"id":"e239a8964ebd1de8","repo":"hashicorp/nomad","slug":"error-opening-reader-at-s-w","errorCode":null,"errorMessage":"error opening reader at %s: %w","messagePattern":"error opening reader at (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/lib/fifo/fifo_unix.go","lineNumber":45,"sourceCode":"\treturn func() (io.ReadCloser, error) {\n\t\treturn OpenReader(path)\n\t}, nil\n}\n\nfunc OpenReader(path string) (io.ReadCloser, error) {\n\tdir := filepath.Dir(path)\n\tbase := filepath.Base(path)\n\n\troot, err := os.OpenRoot(dir)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error opening fifo parent directory %q: %w\", dir, err)\n\t}\n\tdefer root.Close()\n\n\t// also uses O_NOFOLLOW under the hood\n\tf, err := root.OpenFile(base, os.O_RDONLY, 0)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error opening reader at %s: %w\", path, err)\n\t}\n\treturn f, nil\n}\n\n// OpenWriter opens a fifo file for writer, assuming it already exists, returns io.WriteCloser\nfunc OpenWriter(path string) (io.WriteCloser, error) {\n\tdir := filepath.Dir(path)\n\tbase := filepath.Base(path)\n\n\troot, err := os.OpenRoot(dir)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error opening fifo parent directory %q: %w\", dir, err)\n\t}\n\tdefer root.Close()\n\n\t// also uses O_NOFOLLOW under the hood\n\tf, err := root.OpenFile(base, os.O_WRONLY, 0)\n\tif err != nil {","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/lib/fifo/fifo_unix.go#L27-L63","documentation":"OpenReader opens an existing named pipe (FIFO) for reading. It resolves the FIFO relative to its parent directory via os.Root (O_NOFOLLOW) and fails with this wrapped error when the underlying OpenFile on the FIFO itself fails. The wrapped cause is typically ENOENT, EACCES, or a symlink/path-traversal rejection.","triggerScenarios":"Calling fifo.OpenReader(path) when the FIFO does not exist at that path, when the caller lacks read permission on it, when the path component is a symlink, or when an I/O error occurs opening the file.","commonSituations":"Log-monitor consumers starting before the writer creates the FIFO; stale FIFO left behind by a crashed previous run; path typos or container path mismatches (mount not present); SELinux/AppArmor denying read access to the pipe file.","solutions":["Ensure the FIFO exists first (fifo.Create or OpenWriter side) before calling OpenReader, or retry until it appears","Verify the path exists and is a FIFO: os.Stat / unix.Mode(fileMode) & os.ModeNamedPipe","Remove stale FIFOs from prior runs (fifo.Remove) and recreate them","Check filesystem permissions and security-module denials in the wrapped error"],"exampleFix":"// before\nr, err := fifo.OpenReader(\"/run/containerd/io/stdout\")\n// after\nif _, err := os.Stat(\"/run/containerd/io/stdout\"); os.IsNotExist(err) {\n\tif err := fifo.Create(\"/run/containerd/io/stdout\", 0o600); err != nil { return err }\n}\nr, err := fifo.OpenReader(\"/run/containerd/io/stdout\")","handlingStrategy":"retry","validationCode":"func ensureFifo(path string) error {\n\tfi, err := os.Stat(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif fi.Mode()&os.ModeNamedPipe == 0 {\n\t\treturn fmt.Errorf(\"%s is not a fifo\", path)\n\t}\n\treturn nil\n}","typeGuard":"func isNotExistErr(err error) bool { return errors.Is(err, fs.ErrNotExist) }","tryCatchPattern":"r, err := fifo.OpenReader(path)\nif err != nil {\n\tvar pe *fs.PathError\n\tif errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrNotExist) {\n\t\t// wait/retry until writer creates the fifo\n\t}\n\treturn fmt.Errorf(\"open reader %s: %w\", path, err)\n}","preventionTips":["Create the FIFO (fifo.Create) before opening a reader","Use a bounded retry/backoff when racing against the writer","Clean up stale FIFOs from previous runs at startup","Pre-create parent directories with os.MkdirAll"],"tags":["go","filesystem","fifo","file-not-found"],"backgroundTag":"fifo-open-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"}