{"record":{"id":"03e3c4a7d64d608d","repo":"nsqio/nsq","slug":"failed-to-read-metadata-from-s-s","errorCode":null,"errorMessage":"failed to read metadata from %s - %s","messagePattern":"failed to read metadata from (.+?) - (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nsqd/nsqd.go","lineNumber":322,"sourceCode":"\tPaused   bool              `json:\"paused\"`\n\tChannels []ChannelMetadata `json:\"channels\"`\n}\n\n// ChannelMetadata is the collection of persistent information about a channel.\ntype ChannelMetadata struct {\n\tName   string `json:\"name\"`\n\tPaused bool   `json:\"paused\"`\n}\n\nfunc newMetadataFile(opts *Options) string {\n\treturn path.Join(opts.DataPath, \"nsqd.dat\")\n}\n\nfunc readOrEmpty(fn string) ([]byte, error) {\n\tdata, err := os.ReadFile(fn)\n\tif err != nil {\n\t\tif !os.IsNotExist(err) {\n\t\t\treturn nil, fmt.Errorf(\"failed to read metadata from %s - %s\", fn, err)\n\t\t}\n\t}\n\treturn data, nil\n}\n\nfunc writeSyncFile(fn string, data []byte) error {\n\tf, err := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = f.Write(data)\n\tif err == nil {\n\t\terr = f.Sync()\n\t}\n\tcloseErr := f.Close()\n\tif err == nil {\n\t\terr = closeErr","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/nsqio/nsq/blob/85cf10c09c6c3c86160d6f0eb156f62d0efc1648/nsqd/nsqd.go#L304-L340","documentation":"nsqd persists its topic/channel metadata to nsqd.dat in --data-path and reads it on startup (loadNsqdMetadata -> readOrEmpty). os.ReadFile on that file returned an error other than 'file does not exist' — e.g. EACCES, EISDIR, I/O error — so the wrapper reports the filename and cause. A clean missing file is intentionally treated as a fresh start and does NOT produce this error.","triggerScenarios":"--data-path readable-listable but nsqd.dat owned by root with 0600 while nsqd runs as the nsqd user; nsqd.dat is a directory (created by accident or a bad volume mount); a read-only or failing disk/volume (NFS stale handle, EIO); SELinux denial on the file.","commonSituations":"Switching the daemon user (installed as root, later run as 'nsqd'); docker/k8s volume mounts mapping a directory over nsqd.dat path expectations; migrating data between hosts with rsync as root losing ownership; filesystem corruption after an unclean shutdown.","solutions":["Inspect the file: `ls -l /var/lib/nsqd/nsqd.dat` — if ownership/permissions are wrong, `chown nsqd:nsqd nsqd.dat; chmod 600 nsqd.dat`.","If it is a directory or the volume is mis-mounted, fix the mount so --data-path points at a writable directory.","Check for read-only filesystems: `mount | grep <datapath>`; remount rw or move --data-path to healthy storage.","If the file is corrupt/unreadable and disposable, move it aside (mv nsqd.dat nsqd.dat.bak); nsqd then starts fresh and recreates topics as producers publish."],"exampleFix":"# before\n$ ls -l /var/lib/nsqd/nsqd.dat\n-rw------- 1 root root 1214 ... nsqd.dat\n(nsqd runs as user 'nsqd' -> EACCES)\n\n# after\n$ chown nsqd:nsqd /var/lib/nsqd/nsqd.dat\n$ systemctl start nsqd","handlingStrategy":"validation","validationCode":"// before nsqd startup\ninfo, err := os.Stat(filepath.Join(dataPath, \"nsqd.dat\"))\nif err == nil {\n    if info.IsDir() { return errors.New(\"nsqd.dat is a directory\") }\n    if f, err := os.OpenFile(filepath.Join(dataPath, \"nsqd.dat\"), os.O_RDONLY, 0); err != nil {\n        return fmt.Errorf(\"nsqd.dat unreadable: %w\", err)\n    } else { f.Close() }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run nsqd under one dedicated user and keep --data-path owned by it (chown -R nsqd:nsqd).","Keep nsqd.dat off NFS/read-only mounts; use local or block storage.","After running as root once, fix ownership before switching to an unprivileged service user."],"tags":["nsqd","filesystem","permissions","metadata","persistence","startup"],"backgroundTag":null,"analyzedSha":"85cf10c09c6c3c86160d6f0eb156f62d0efc1648","analyzedAt":"2026-08-16T00:53:05.009Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}