hashicorp/nomad · info
no more logs
Error message
no more logs
What it means
ErrNoMoreLogs is a sentinel error exported from helper/raftutil indicating the FSM helper has applied every available Raft log: nextIdx has passed logLastIdx. It is not a failure — ApplyUntil and ApplyAll treat it as the normal termination signal for replaying logs.
Source
Thrown at helper/raftutil/fsm.go:20
// SPDX-License-Identifier: BUSL-1.1
package raftutil
import (
"context"
"fmt"
"io"
"strings"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-memdb"
"github.com/hashicorp/nomad/nomad"
"github.com/hashicorp/nomad/nomad/state"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/hashicorp/raft"
)
var ErrNoMoreLogs = fmt.Errorf("no more logs")
type nomadFSM interface {
raft.FSM
State() *state.StateStore
Restore(io.ReadCloser) error
RestoreWithFilter(io.ReadCloser, *nomad.FSMFilter) error
}
type FSMHelper struct {
path string
logger hclog.Logger
// nomad state
store RaftStore
fsm nomadFSM
snaps *raft.FileSnapshotStore
View on GitHub (pinned to 482b49bf1a)
Solutions
- Treat it as success: compare with errors.Is(err, raftutil.ErrNoMoreLogs) and stop the replay loop
- No fix needed — this signals normal completion of log replay
Example fix
// before
idx, term, err := f.ApplyNext()
if err != nil { return err }
// after
idx, term, err := f.ApplyNext()
if errors.Is(err, raftutil.ErrNoMoreLogs) {
return lastIdx, lastTerm, nil // replay complete
} else if err != nil {
return err
} Defensive patterns
Strategy: type-guard
Type guard
func isNoMoreLogs(err error) bool { return errors.Is(err, raftutil.ErrNoMoreLogs) } Try / catch
idx, term, err := f.ApplyNext()
if errors.Is(err, raftutil.ErrNoMoreLogs) {
return lastIdx, lastTerm, nil // success: log exhausted
}
if err != nil {
return err
} Prevention
- Always compare with errors.Is against the exported ErrNoMoreLogs sentinel, never string matching
- Treat it as a success/termination signal in replay loops
- Structure replay loops to break on this sentinel explicitly
When it happens
Trigger: Calling ApplyNext on an FSMHelper whose nextIdx exceeds the store's last log index; it is also returned by ApplyUntil and ApplyAll when replay reaches the end of the log.
Common situations: Tooling that replays a Nomad server's Raft log offline (debugging, migration, state inspection) reaching the end of the log; testing with TestSampleInvariant where replay exhaustion is expected.
Related errors
- failed to find raft store in %v: %v
- failed to open raft store %v: %v
- failed to open snapshot dir: %v
- missing logs [%v, %v]
- failed to read log entry at index %d: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/3d22cb90375740c9.
Report an issue: GitHub.