hashicorp/nomad · error

Multi-Cluster Consul is unlicensed.

Error message

Multi-Cluster Consul is unlicensed.

What it means

NamespaceConsulConfiguration.Validate in the CE build returns "Multi-Cluster Consul is unlicensed." for any non-nil per-namespace Consul configuration. Multi-Cluster Consul (per-namespace Consul cluster/namespace targeting) is enterprise-only, so the OSS stub rejects the block outright.

Source

Thrown at nomad/structs/structs_ce.go:39

		return errors.New("Node Pools Governance is unlicensed.")
	}
	return nil
}

func (n *NamespaceVaultConfiguration) Canonicalize() {}

func (n *NamespaceVaultConfiguration) Validate() error {
	if n != nil {
		return errors.New("Multi-Cluster Vault is unlicensed.")
	}
	return nil
}

func (n *NamespaceConsulConfiguration) Canonicalize() {}

func (n *NamespaceConsulConfiguration) Validate() error {
	if n != nil {
		return errors.New("Multi-Cluster Consul is unlicensed.")
	}
	return nil
}

func (m *Multiregion) Validate(jobType string, jobDatacenters []string) error {
	if m != nil {
		return errors.New("Multiregion jobs are unlicensed.")
	}

	return nil
}

func (p *ScalingPolicy) validateType() multierror.Error {
	var mErr multierror.Error

	// Check policy type and target
	switch p.Type {
	case ScalingPolicyTypeHorizontal:

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Remove the per-namespace consul configuration block and rely on agent-level Consul configuration.
  2. Upgrade to Nomad Enterprise with Multi-Cluster Consul entitlement and install a license.
  3. Nil the NamespaceConsulConfiguration field in code that constructs namespace objects.

Example fix

// before
ns.ConsulConfiguration = &structs.NamespaceConsulConfiguration{DefaultNamespace: "default"}
// after
ns.ConsulConfiguration = nil // Multi-Cluster Consul requires Enterprise license
Defensive patterns

Strategy: validation

Validate before calling

if ns.ConsulConfiguration != nil {
	return errors.New("multi-cluster consul requires Nomad Enterprise")
}

Type guard

func consulLicensed(cfg *structs.NamespaceConsulConfiguration) bool { return cfg == nil }

Try / catch

if err := ns.Validate(); err != nil && strings.Contains(err.Error(), "unlicensed") {
	ns.ConsulConfiguration = nil // retry without the block
}

Prevention

When it happens

Trigger: Submitting a namespace whose NamespaceConsulConfiguration is non-nil (consul { cluster = "..." namespace = "..." } within a namespace spec) to a community-edition Nomad agent.

Common situations: Migrating namespace definitions from an Enterprise cluster to OSS; templates that emit the consul block unconditionally; attempting per-namespace Consul namespacing without an Enterprise license.

Related errors


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