hashicorp/nomad · error

cannot reload agent with nil configuration

Error message

cannot reload agent with nil configuration

What it means

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.

Source

Thrown at command/agent/agent.go:1649

func (a *Agent) ConfigReload() error {
	if a.configReloader == nil {
		return nil
	}
	return a.configReloader()
}

// Reload handles configuration changes for the agent. Provides a method that
// is easier to unit test, as this action is invoked via SIGHUP.
func (a *Agent) Reload(newConfig *Config) error {
	a.configLock.Lock()
	defer a.configLock.Unlock()

	current := a.config.Copy()

	updatedLogging := newConfig != nil && (newConfig.LogLevel != current.LogLevel)

	if newConfig == nil || newConfig.TLSConfig == nil && !updatedLogging {
		return fmt.Errorf("cannot reload agent with nil configuration")
	}

	if updatedLogging {
		current.LogLevel = newConfig.LogLevel
		a.logger.SetLevel(log.LevelFromString(current.LogLevel))
	}

	current.Files = slices.Clone(newConfig.Files)
	current.ConfigPaths = slices.Clone(newConfig.ConfigPaths)

	// Update eventer config
	if newConfig.Audit != nil {
		if err := a.entReloadEventer(newConfig.Audit); err != nil {
			return err
		}
	}
	// Allow auditor to call reopen regardless of config changes
	// This is primarily for enterprise audit logging to allow the underlying

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Ensure the config file parses before signaling SIGHUP — run `nomad config validate` on it
  2. Pass a non-nil *Config to Reload with at least TLSConfig or a changed LogLevel set
  3. Fix the signal handler so a config parse failure is reported instead of passing nil to Reload

Example fix

// before
agent.Reload(nil)
// after
newConf, err := config.ParseConfigFile(path)
if err != nil { return err }
if err := agent.Reload(newConf); err != nil { return err }
Defensive patterns

Strategy: validation

Validate before calling

if newConf == nil {
    return errors.New("reload aborted: new configuration is nil")
}

Type guard

func isValidReloadConfig(c *agent.Config) bool {
    return c != nil && (c.TLSConfig != nil || c.LogLevel != "")
}

Try / catch

if err := srv.Agent.Reload(newConf); err != nil {
    if strings.Contains(err.Error(), "nil configuration") {
        return fmt.Errorf("reload needs non-nil config with TLS or log level: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/c98ef00bf5328fea. Report an issue: GitHub.