hashicorp/nomad · error

nil consul config

Error message

nil consul config

What it means

NewConsulClientFactory returns a ConsulClientFunc that builds a Consul client from a *config.ConsulConfig. The factory immediately rejects a nil config because every later step (logger naming, partition lookup, API client construction) depends on fields of that config, and a nil dereference would panic instead of returning a clean error.

Source

Thrown at client/consul/consul.go:87

	preflightCheckBaseInterval time.Duration
}

// ConsulClientFunc creates a new Consul client for the specific Consul config
type ConsulClientFunc func(config *config.ConsulConfig, logger hclog.Logger) (Client, error)

// NodeGetter breaks a circular dependency between client/config.Config and this
// package
type NodeGetter interface {
	GetNode() *structs.Node
}

// NewConsulClientFactory returns a ConsulClientFunc that closes over the
// partition
func NewConsulClientFactory(nodeGetter NodeGetter) ConsulClientFunc {

	return func(config *config.ConsulConfig, logger hclog.Logger) (Client, error) {
		if config == nil {
			return nil, fmt.Errorf("nil consul config")
		}

		logger = logger.Named("consul").With("name", config.Name)

		node := nodeGetter.GetNode()
		partition := node.Attributes["consul.partition"]
		preflightCheckTimeout := durationFromMeta(
			node, "consul.token_preflight_check.timeout", time.Second*10)
		preflightCheckBaseInterval := durationFromMeta(
			node, "consul.token_preflight_check.base", time.Millisecond*500)

		c := &consulClient{
			config:                     config,
			logger:                     logger,
			partition:                  partition,
			preflightCheckTimeout:      preflightCheckTimeout,
			preflightCheckBaseInterval: preflightCheckBaseInterval,
		}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Add a `consul { ... }` stanza to the Nomad client agent config so a valid ConsulConfig is built
  2. Check the config-loading code path for a bug that leaves ConsulConfig nil (e.g. a struct pointer never initialized after merge)
  3. Upgrade Nomad if a known config-merge regression drops the Consul config; otherwise file an issue with the agent config
  4. In tests, pass a valid config.ConsulConfig (even minimal) to the ConsulClientFunc

Example fix

// before
clientFactory := consul.NewConsulClientFactory(nodeGetter)
client, err := clientFactory(nil, logger) // nil config
// after
ccfg := &config.ConsulConfig{Name: "default", ServerServiceName: "nomad", ...}
client, err := clientFactory(ccfg, logger)
Defensive patterns

Strategy: validation

Validate before calling

if cfg == nil {
    return fmt.Errorf("consul client requires a non-nil *config.ConsulConfig")
}
client, err := consulFn(cfg, logger)

Type guard

func hasConsulConfig(cfg *config.ConsulConfig) bool { return cfg != nil }

Prevention

When it happens

Trigger: Creating the Consul client with a nil *config.ConsulConfig — e.g. the client's config assembly produced no Consul stanza or the Consul config struct was dropped/omitted during config parsing before ConsulClientFunc is invoked.

Common situations: Running a Nomad client whose configuration omitted the entire `consul { }` block while Consul features are still enabled; a config merge/unmarshal bug that drops ConsulConfig; tests constructing the client directly without a Consul config.

Related errors


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