nsqio/nsq · error
failed to read metadata from %s - %s
Error message
failed to read metadata from %s - %s
What it means
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.
Source
Thrown at nsqd/nsqd.go:322
Paused bool `json:"paused"`
Channels []ChannelMetadata `json:"channels"`
}
// ChannelMetadata is the collection of persistent information about a channel.
type ChannelMetadata struct {
Name string `json:"name"`
Paused bool `json:"paused"`
}
func newMetadataFile(opts *Options) string {
return path.Join(opts.DataPath, "nsqd.dat")
}
func readOrEmpty(fn string) ([]byte, error) {
data, err := os.ReadFile(fn)
if err != nil {
if !os.IsNotExist(err) {
return nil, fmt.Errorf("failed to read metadata from %s - %s", fn, err)
}
}
return data, nil
}
func writeSyncFile(fn string, data []byte) error {
f, err := os.OpenFile(fn, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return err
}
_, err = f.Write(data)
if err == nil {
err = f.Sync()
}
closeErr := f.Close()
if err == nil {
err = closeErrView on GitHub (pinned to 85cf10c09c)
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.
Example fix
# before $ ls -l /var/lib/nsqd/nsqd.dat -rw------- 1 root root 1214 ... nsqd.dat (nsqd runs as user 'nsqd' -> EACCES) # after $ chown nsqd:nsqd /var/lib/nsqd/nsqd.dat $ systemctl start nsqd
Defensive patterns
Strategy: validation
Validate before calling
// before nsqd startup
info, err := os.Stat(filepath.Join(dataPath, "nsqd.dat"))
if err == nil {
if info.IsDir() { return errors.New("nsqd.dat is a directory") }
if f, err := os.OpenFile(filepath.Join(dataPath, "nsqd.dat"), os.O_RDONLY, 0); err != nil {
return fmt.Errorf("nsqd.dat unreadable: %w", err)
} else { f.Close() }
} Prevention
- 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.
When it happens
Trigger: --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.
Common situations: 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.
Related errors
- failed to parse metadata in %s - %s
- cannot flock directory %s - %s (possibly in use by another i
- failed to read TLS root CA file %s - %s
- failed to append certificate to pool
- unknown tlsVersionOption %q
AI-assisted analysis of nsqio/nsq@85cf10c09c (2026-08-16).
Data as JSON: /api/errors/03e3c4a7d64d608d.
Report an issue: GitHub.