{"record":{"id":"c34a51bd73426e04","repo":"hashicorp/nomad","slug":"reload-given-a-nil-config","errorCode":null,"errorMessage":"Reload given a nil config","messagePattern":"Reload given a nil config","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/server.go","lineNumber":914,"sourceCode":"\t\t// to evaluate during the RC period if this interim situation is\n\t\t// not too confusing for operators.\n\n\t\t// TODO (alexdadgar) When we take a later new version of the Raft\n\t\t// library it won't try to complete replication, so this peer\n\t\t// may not realize that it has been removed. Need to revisit this\n\t\t// and the warning here.\n\t\tif !left {\n\t\t\ts.logger.Warn(\"failed to leave raft configuration gracefully, timeout\")\n\t\t}\n\t}\n\treturn nil\n}\n\n// Reload handles a config reload specific to server-only configuration. Not\n// all config fields can handle a reload.\nfunc (s *Server) Reload(newConfig *Config) error {\n\tif newConfig == nil {\n\t\treturn fmt.Errorf(\"Reload given a nil config\")\n\t}\n\n\tvar mErr multierror.Error\n\n\tshouldReloadTLS, err := tlsutil.ShouldReloadRPCConnections(s.config.TLSConfig, newConfig.TLSConfig)\n\tif err != nil {\n\t\ts.logger.Error(\"error checking whether to reload TLS configuration\", \"error\", err)\n\t}\n\n\tif shouldReloadTLS {\n\t\tif err := s.reloadTLSConnections(newConfig.TLSConfig); err != nil {\n\t\t\ts.logger.Error(\"error reloading server TLS configuration\", \"error\", err)\n\t\t\t_ = multierror.Append(&mErr, err)\n\t\t}\n\t}\n\n\tif newConfig.LicenseConfig.LicenseEnvBytes != \"\" || newConfig.LicenseConfig.LicensePath != \"\" {\n\t\tif err = s.EnterpriseState.ReloadLicense(newConfig); err != nil {","sourceCodeStart":896,"sourceCodeEnd":932,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/server.go#L896-L932","documentation":"Server.Reload was called with a nil configuration object; the reload path guards against a missing config before applying server-only config changes.","triggerScenarios":"Calling Server.Reload(nil) programmatically — e.g. a test, integration harness, or wrapper that constructs the new config conditionally and passes nil when parsing fails or the config map is empty.","commonSituations":"Internal callers/tests of the agent package, config reload tooling that skips config parsing on error yet still invokes Reload, or API integrations embedding Nomad server code.","solutions":["Ensure the caller builds and parses a valid Config before invoking Reload.","Return/handle the config-parse error upstream instead of passing nil through.","If reload is conditional, check for nil newConfig before calling Reload."],"exampleFix":"// before\ncfg, err := loadConfig(path)\nreturn srv.Reload(cfg) // cfg is nil when loadConfig failed\n// after\ncfg, err := loadConfig(path)\nif err != nil {\n    return err\n}\nreturn srv.Reload(cfg)","handlingStrategy":"type-guard","validationCode":"func safeReload(srv *nomad.Server, cfg *nomad.Config) error {\n    if cfg == nil {\n        return errors.New(\"reload aborted: nil config\")\n    }\n    return srv.Reload(cfg)\n}","typeGuard":"func validReloadConfig(c *nomad.Config) bool { return c != nil }","tryCatchPattern":"if err := srv.Reload(cfg); err != nil && strings.Contains(err.Error(), \"nil config\") {\n    return fmt.Errorf(\"caller bug: reload invoked without parsed config: %w\", err)\n}","preventionTips":["Never call Reload with a config that failed to parse; propagate the parse error instead.","Wrap Reload in a nil-check helper in integration code."],"tags":["reload","nil-config","api-misuse"],"backgroundTag":"nil-config-argument","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"}