hashicorp/nomad · error

failed to open WAL logs: %v

Error message

failed to open WAL logs: %v

What it means

raftStateInfoWAL handles the case where path p is a directory containing a Raft WAL (write-ahead log). This error wraps a failure of raftwal.Open on that directory — the WAL could not be opened at all: missing/corrupt segment files, wrong directory contents, or I/O errors. The store is not yet open so no cleanup is needed before returning.

Source

Thrown at helper/raftutil/state.go:83

	}

	firstIdx, err = s.FirstIndex()
	if err != nil {
		return nil, 0, 0, fmt.Errorf("failed to fetch first index: %v", err)
	}

	lastIdx, err = s.LastIndex()
	if err != nil {
		return nil, 0, 0, fmt.Errorf("failed to fetch last index: %v", err)
	}

	return s, firstIdx, lastIdx, nil
}

func raftStateInfoWAL(p string) (store RaftStore, firstIdx uint64, lastIdx uint64, err error) {
	s, err := raftwal.Open(p)
	if err != nil {
		return nil, 0, 0, fmt.Errorf("failed to open WAL logs: %v", err)
	}

	firstIdx, err = s.FirstIndex()
	if err != nil {
		s.Close()
		return nil, 0, 0, fmt.Errorf("failed to fetch first index: %v", err)
	}

	lastIdx, err = s.LastIndex()
	if err != nil {
		s.Close()
		return nil, 0, 0, fmt.Errorf("failed to fetch last index: %v", err)
	}

	return s, firstIdx, lastIdx, nil
}

// LogEntries reads the raft logs found in the data directory found at

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify the directory actually contains Raft WAL segments (correct file naming) and not another store layout.
  2. Fix directory/file permissions so the segment files are readable.
  3. Check the embedded error for specific segment corruption; restore WAL/state from a snapshot if segments are damaged.
  4. Take a consistent copy of the WAL directory while the agent is stopped and inspect that copy.
  5. If the node actually uses BoltDB state, pass the raft.db file path so raftStateInfoBoltDB is used instead.

Example fix

// before
store, _, _, err := raftutil.RaftStateInfo("/var/lib/consul/raft") // dir without WAL segments

// after
p := "/var/lib/consul/raft/raft.db" // BoltDB state: pass the file, not the dir
store, _, _, err := raftutil.RaftStateInfo(p)
Defensive patterns

Strategy: validation

Validate before calling

func validateWALDir(p string) error {
    fi, err := os.Stat(p)
    if err != nil {
        return err
    }
    if !fi.IsDir() {
        return fmt.Errorf("%s is not a directory", p)
    }
    entries, err := os.ReadDir(p)
    if err != nil {
        return err
    }
    if len(entries) == 0 {
        return fmt.Errorf("%s contains no WAL segments", p)
    }
    return nil
}

Try / catch

store, _, _, err := raftutil.RaftStateInfo(walDir)
if err != nil {
    if strings.Contains(err.Error(), "failed to open WAL logs") {
        log.Printf("WAL unreadable or wrong directory: %v", err)
    }
}

Prevention

When it happens

Trigger: raftwal.Open(p) failing when p is a directory: empty or nonexistent WAL segment files, corrupt segment naming/content, a directory that is a BoltDB state dir misdetected as WAL, or permission/I-O errors opening segment files.

Common situations: Inspecting a WAL-enabled node's directory where segments were partially written before a crash, pointing at an unrelated directory that happens to be a dir (so it is routed to the WAL path), or running without read permission on the WAL segment files.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/9a1cf28658569d48. Report an issue: GitHub.