{"record":{"id":"0bccec473948e31e","repo":"hashicorp/nomad","slug":"invalid-configuration-q-scheduler-not-enabled","errorCode":null,"errorMessage":"invalid configuration: %q scheduler not enabled","messagePattern":"invalid configuration: %q scheduler not enabled","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/server.go","lineNumber":1966,"sourceCode":"\tif len(poolArgs.EnabledSchedulers) == 0 || poolArgs.NumSchedulers == 0 {\n\t\ts.logger.Warn(\"no enabled schedulers\")\n\t\treturn nil\n\t}\n\n\t// Check if the core scheduler is not enabled\n\tfoundCore := false\n\tfor _, sched := range poolArgs.EnabledSchedulers {\n\t\tif sched == structs.JobTypeCore {\n\t\t\tfoundCore = true\n\t\t\tcontinue\n\t\t}\n\n\t\tif _, ok := scheduler.BuiltinSchedulers[sched]; !ok {\n\t\t\treturn fmt.Errorf(\"invalid configuration: unknown scheduler %q in enabled schedulers\", sched)\n\t\t}\n\t}\n\tif !foundCore {\n\t\treturn fmt.Errorf(\"invalid configuration: %q scheduler not enabled\", structs.JobTypeCore)\n\t}\n\n\ts.logger.Info(\"starting scheduling worker(s)\", \"num_workers\", poolArgs.NumSchedulers, \"schedulers\", poolArgs.EnabledSchedulers)\n\t// Start the workers\n\n\tfor i := 0; i < s.config.NumSchedulers; i++ {\n\t\tif w, err := NewWorker(ctx, s, poolArgs); err != nil {\n\t\t\treturn err\n\t\t} else {\n\t\t\ts.logger.Debug(\"started scheduling worker\", \"id\", w.ID(), \"index\", i+1, \"of\", s.config.NumSchedulers)\n\t\t\ts.workerShutdownGroup.AddCh(w.ShutdownCh())\n\t\t\ts.workers = append(s.workers, w)\n\t\t}\n\t}\n\ts.logger.Info(\"started scheduling worker(s)\", \"num_workers\", s.config.NumSchedulers, \"schedulers\", s.config.EnabledSchedulers)\n\treturn nil\n}\n","sourceCodeStart":1948,"sourceCodeEnd":1984,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/server.go#L1948-L1984","documentation":"Nomad requires the internal 'core' scheduler (job type 'core', used for garbage collection, evals of system internals, etc.) to always be enabled. If the computed enabled_schedulers set omits it — either directly via config or because scheduling for it was disabled — worker setup fails validation.","triggerScenarios":"server.stanza enabled_schedulers lists schedulers but omits \"core\", so foundCore stays false after the validation loop.","commonSituations":"Operator set enabled_schedulers = [\"service\", \"batch\"] forgetting the core scheduler; config automation filtering 'core' out as an internal name; copy-pasted config where core was stripped.","solutions":["Add \"core\" to enabled_schedulers in the server config and restart","Remove the enabled_schedulers line to accept the default set (which includes core)","Validate config with nomad agent -config-check before deploying","If automation builds the scheduler list, special-case JobTypeCore to always include it"],"exampleFix":"// before\nenabled_schedulers = [\"service\", \"batch\", \"system\"]\n// after\nenabled_schedulers = [\"service\", \"batch\", \"system\", \"core\"]","handlingStrategy":"validation","validationCode":"// Ensure 'core' is always present in enabled schedulers\nlet enabled = ['service', 'batch', 'system']; // from config\nif (!enabled.includes('core')) enabled = ['core', ...enabled];","typeGuard":null,"tryCatchPattern":"try {\n  startNomadServer();\n} catch (e) {\n  if (String(e).includes('scheduler not enabled')) {\n    addCoreSchedulerToConfig();\n    startNomadServer();\n  } else throw e;\n}","preventionTips":["Always include \"core\" when overriding enabled_schedulers","Prefer omitting enabled_schedulers to accept defaults","Add a config-lint rule asserting JobTypeCore presence"],"tags":["configuration","scheduler","core","startup"],"backgroundTag":"invalid-scheduler-configuration","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"}