{"record":{"id":"c6934fd3a593fbaa","repo":"hashicorp/nomad","slug":"panic-r","errorCode":null,"errorMessage":"panic(r)","messagePattern":"panic\\(r\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"helper/raftutil/fsm.go","lineNumber":150,"sourceCode":"\t\treturn 0, 0, ErrNoMoreLogs\n\t}\n\n\tvar e raft.Log\n\terr = f.store.GetLog(f.nextIdx, &e)\n\tif err != nil {\n\t\treturn 0, 0, fmt.Errorf(\"failed to read log entry at index %d: %v\", f.nextIdx, err)\n\t}\n\n\tdefer func() {\n\t\tr := recover()\n\t\tif r != nil && strings.HasPrefix(fmt.Sprint(r), \"failed to apply request\") {\n\t\t\t// Enterprise specific log entries will fail to load in OSS repository with \"failed to apply request.\"\n\t\t\t// If not relevant to investigation, we can ignore them and simply worn.\n\t\t\tf.logger.Warn(\"failed to apply log; loading Enterprise data-dir in OSS binary?\", \"index\", e.Index)\n\n\t\t\tf.nextIdx++\n\t\t} else if r != nil {\n\t\t\tpanic(r)\n\t\t}\n\t}()\n\n\tif e.Type == raft.LogCommand {\n\t\tf.fsm.Apply(&e)\n\t}\n\n\tf.nextIdx++\n\treturn e.Index, e.Term, nil\n}\n\n// ApplyUntil applies all raft entries until (inclusive) the passed index.\nfunc (f *FSMHelper) ApplyUntil(stopIdx uint64) (idx uint64, term uint64, err error) {\n\tvar lastIdx, lastTerm uint64\n\tfor {\n\t\tidx, term, err := f.ApplyNext()\n\t\tif err == ErrNoMoreLogs {\n\t\t\treturn lastIdx, lastTerm, nil","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/raftutil/fsm.go#L132-L168","documentation":"FSMHelper.ApplyNext replays a Raft log entry through the embedded FSM, recovering panics from Apply. It swallows panics starting with 'failed to apply request' (enterprise-only log entries that OSS binaries can't apply), but any other panic is deliberately re-panicked because it represents a genuine, unexpected FSM bug.","triggerScenarios":"Calling ApplyNext/ApplyUntil/ApplyAll (e.g. during raftutil snapshot/restore tooling or dev-mode FSM replay) when f.fsm.Apply panics with a message other than 'failed to apply request'.","commonSituations":"Loading an OSS data-dir containing malformed or corrupted Raft log entries whose application trips a nil map/nil pointer inside the FSM; replaying logs with entry types the local FSM code can't handle due to version skew.","solutions":["Check the panic message: if it is 'failed to apply request', it is intentionally ignored as an Enterprise entry in OSS","If re-panicked, inspect the Raft log at the reported index and the FSM code path that panicked; fix or remove the offending entry","Ensure the binary and data-dir versions match (version skew between log writer and FSM applier is a common cause)","Use a Nomad-enterprise binary if the data-dir contains enterprise log entries"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        logger.Error(\"FSM replay panicked on log entry\", \"panic\", r, \"index\", nextIdx)\n        // abort replay / quarantine the log entry\n    }\n}()","preventionTips":["Match binary version to the data-dir version before replay","Use the enterprise binary for enterprise data-dirs","Back up the raft log store before running raftutil snapshot/replay tools","Investigate any panic message not starting with 'failed to apply request' as a real bug"],"tags":["raft","fsm","repanic","data-corruption"],"backgroundTag":"raft-log-apply-panic","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"}