{"record":{"id":"c98ef00bf5328fea","repo":"hashicorp/nomad","slug":"cannot-reload-agent-with-nil-configuration","errorCode":null,"errorMessage":"cannot reload agent with nil configuration","messagePattern":"cannot reload agent with nil configuration","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/agent.go","lineNumber":1649,"sourceCode":"func (a *Agent) ConfigReload() error {\n\tif a.configReloader == nil {\n\t\treturn nil\n\t}\n\treturn a.configReloader()\n}\n\n// Reload handles configuration changes for the agent. Provides a method that\n// is easier to unit test, as this action is invoked via SIGHUP.\nfunc (a *Agent) Reload(newConfig *Config) error {\n\ta.configLock.Lock()\n\tdefer a.configLock.Unlock()\n\n\tcurrent := a.config.Copy()\n\n\tupdatedLogging := newConfig != nil && (newConfig.LogLevel != current.LogLevel)\n\n\tif newConfig == nil || newConfig.TLSConfig == nil && !updatedLogging {\n\t\treturn fmt.Errorf(\"cannot reload agent with nil configuration\")\n\t}\n\n\tif updatedLogging {\n\t\tcurrent.LogLevel = newConfig.LogLevel\n\t\ta.logger.SetLevel(log.LevelFromString(current.LogLevel))\n\t}\n\n\tcurrent.Files = slices.Clone(newConfig.Files)\n\tcurrent.ConfigPaths = slices.Clone(newConfig.ConfigPaths)\n\n\t// Update eventer config\n\tif newConfig.Audit != nil {\n\t\tif err := a.entReloadEventer(newConfig.Audit); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t// Allow auditor to call reopen regardless of config changes\n\t// This is primarily for enterprise audit logging to allow the underlying","sourceCodeStart":1631,"sourceCodeEnd":1667,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/agent.go#L1631-L1667","documentation":"Agent.Reload rejects a reload request when the new configuration is nil or, when non-nil, carries no TLSConfig and no changed LogLevel — i.e. there is nothing meaningful to reload. The agent refuses rather than performing a no-op or a reload from unknown state.","triggerScenarios":"Calling agent.Reload(nil) (e.g. SIGHUP handler path handleReload with failed config parsing, or test helpers TestServer_Reload_TLS_* passing nil), or calling Reload with a newConfig whose TLSConfig is nil while LogLevel is unchanged.","commonSituations":"Sending SIGHUP to the agent when the config file failed to re-parse so newConfig is nil; programmatically invoking Reload without constructing a Config; test code reloading with an empty Config struct.","solutions":["Ensure the config file parses before signaling SIGHUP — run `nomad config validate` on it","Pass a non-nil *Config to Reload with at least TLSConfig or a changed LogLevel set","Fix the signal handler so a config parse failure is reported instead of passing nil to Reload"],"exampleFix":"// before\nagent.Reload(nil)\n// after\nnewConf, err := config.ParseConfigFile(path)\nif err != nil { return err }\nif err := agent.Reload(newConf); err != nil { return err }","handlingStrategy":"validation","validationCode":"if newConf == nil {\n    return errors.New(\"reload aborted: new configuration is nil\")\n}","typeGuard":"func isValidReloadConfig(c *agent.Config) bool {\n    return c != nil && (c.TLSConfig != nil || c.LogLevel != \"\")\n}","tryCatchPattern":"if err := srv.Agent.Reload(newConf); err != nil {\n    if strings.Contains(err.Error(), \"nil configuration\") {\n        return fmt.Errorf(\"reload needs non-nil config with TLS or log level: %w\", err)\n    }\n    return err\n}","preventionTips":["Validate config parse success before SIGHUP/Reload","Never call Reload(nil); build a full Config copy","In tests, always pass a Config with TLSConfig or LogLevel set"],"tags":["nomad","reload","tls","configuration"],"backgroundTag":"nil-config","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"}