{"record":{"id":"44fd4308d5d45855","repo":"hashicorp/nomad","slug":"downgrading-raft-is-not-supported-current-version","errorCode":null,"errorMessage":"downgrading Raft is not supported, current version is %d, previous version was %d","messagePattern":"downgrading Raft is not supported, current version is (.+?), previous version was (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"nomad/server.go","lineNumber":1733,"sourceCode":"\n\t\ts.logger.Warn(fmt.Sprintf(\"unable to read Raft version file, %s\", baseWarning), \"error\", err)\n\t\treturn nil\n\t}\n\n\tv, err := os.ReadFile(path)\n\tif err != nil {\n\t\ts.logger.Warn(fmt.Sprintf(\"unable to read Raft version file, %s\", baseWarning), \"error\", err)\n\t\treturn nil\n\t}\n\n\tpreviousVersion, err := strconv.Atoi(strings.TrimSpace(string(v)))\n\tif err != nil {\n\t\ts.logger.Warn(fmt.Sprintf(\"invalid Raft protocol version in Raft version file, %s\", baseWarning), \"error\", err)\n\t\treturn nil\n\t}\n\n\tif raft.ProtocolVersion(previousVersion) > raftVersion {\n\t\treturn fmt.Errorf(\"downgrading Raft is not supported, current version is %d, previous version was %d\", raftVersion, previousVersion)\n\t}\n\n\treturn nil\n}\n\n// setupSerf is used to setup and initialize a Serf\nfunc (s *Server) setupSerf(conf *serf.Config, ch chan serf.Event, path string) (*serf.Serf, error) {\n\tconf.Init()\n\tconf.NodeName = fmt.Sprintf(\"%s.%s\", s.config.NodeName, s.config.Region)\n\tconf.Tags[\"role\"] = \"nomad\"\n\tconf.Tags[\"region\"] = s.config.Region\n\tconf.Tags[\"dc\"] = s.config.Datacenter\n\tconf.Tags[\"build\"] = s.config.Build\n\tconf.Tags[\"revision\"] = s.config.Revision\n\tconf.Tags[\"vsn\"] = deprecatedAPIMajorVersionStr // for Nomad <= v1.2 compat\n\tconf.Tags[\"raft_vsn\"] = fmt.Sprintf(\"%d\", s.config.RaftConfig.ProtocolVersion)\n\tconf.Tags[\"id\"] = s.config.NodeID\n\tconf.Tags[\"rpc_addr\"] = s.clientRpcAdvertise.(*net.TCPAddr).IP.String()         // Address that clients will use to RPC to servers","sourceCodeStart":1715,"sourceCodeEnd":1751,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/server.go#L1715-L1751","documentation":"Nomad persists the previously used Raft protocol version in a Raft version file under the data dir. On startup, if the stored previous version is higher than the configured raft.protocol_version, startup refuses to proceed, because downgrading the Raft protocol can corrupt the log store. This protects against rolling back an upgraded cluster.","triggerScenarios":"Server start where raft.ProtocolVersion(previousVersion) > raftVersion — i.e. the agent previously ran with a higher protocol_version than the current config value, or the Raft version file is corrupt/stale (the code path logs 'invalid Raft protocol version in Raft version file' as a warning just above).","commonSituations":"Operator rolled back a Nomad upgrade from 0.8+ to an older binary while keeping the same data_dir; config management (Chef/Puppet/Terraform) reset protocol_version from 3 to 2; copying a data dir from a newer cluster to an older node.","solutions":["Restore protocol_version in the server config to the value previously used (typically 3) and restart","If you truly must run an older Nomad, do NOT reuse the upgraded data_dir — start with an empty data dir","Verify the Raft version file under data_dir/raft/ is intact; if corrupt, correct it or restore from backup","Plan upgrades as one-way: snapshot the data dir before upgrading so rollback uses the backup, not the live dir"],"exampleFix":"// before\nserver {\n  protocol_version = 2\n}\n// after\nserver {\n  protocol_version = 3\n}","handlingStrategy":"validation","validationCode":"// Compare configured protocol_version against the stored Raft version file before start\nconst configured = 3; // from server config\nconst verFile = dataDir + '/raft/versionfile'; // location per Nomad docs\nif (fs.existsSync(verFile)) {\n  const prev = parseInt(fs.readFileSync(verFile, 'utf8').trim(), 10);\n  if (!Number.isNaN(prev) && prev > configured) throw new Error('downgrading raft protocol is not supported');\n}","typeGuard":null,"tryCatchPattern":"try {\n  startNomadServer();\n} catch (e) {\n  if (String(e).includes('downgrading Raft is not supported')) {\n    throw new Error('Restore protocol_version=' + extractPrevVersion(e) + ' in config, or start with an empty data_dir');\n  }\n  throw e;\n}","preventionTips":["Treat Raft protocol upgrades as one-way; snapshot the data dir before upgrading Nomad","Pin protocol_version in config management so rollback tooling can't lower it","Never reuse a newer cluster's data dir with an older Nomad binary"],"tags":["raft","versioning","upgrade","configuration"],"backgroundTag":"raft-protocol-version-downgrade","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"}