temporalio/temporal · critical

Empty cluster information

Error message

Empty cluster information

What it means

NewMetadata in common/cluster/metadata.go validates its inputs at construction and panics with "Empty cluster information" when the provided clusterInfo map has no entries. Cluster metadata needs at least the current (and master) cluster defined; an empty map means the service cannot reason about replication at all, so it fails fast at startup.

Source

Thrown at common/cluster/metadata.go:146

		versionToClusterName map[int64]string

		clusterCallbackLock   sync.RWMutex
		clusterChangeCallback map[any]CallbackFn
	}
)

func NewMetadata(
	enableGlobalNamespace bool,
	failoverVersionIncrement int64,
	masterClusterName string,
	currentClusterName string,
	clusterInfo map[string]ClusterInformation,
	clusterMetadataStore persistence.ClusterMetadataManager,
	refreshDuration dynamicconfig.DurationPropertyFn,
	logger log.Logger,
) Metadata {
	if len(clusterInfo) == 0 {
		panic("Empty cluster information")
	} else if len(masterClusterName) == 0 {
		panic("Master cluster name is empty")
	} else if len(currentClusterName) == 0 {
		panic("Current cluster name is empty")
	} else if failoverVersionIncrement == 0 || failoverVersionIncrement > math.MaxInt32 {
		panic("Version increment <= 0 or > 2147483647")
	}

	versionToClusterName, err := updateVersionToClusterName(clusterInfo, failoverVersionIncrement)
	if err != nil {
		// nolint:forbidigo // matches the other startup-config panics in this constructor
		panic(err.Error())
	}
	if _, ok := clusterInfo[currentClusterName]; !ok {
		panic("Current cluster is not specified in cluster info")
	}
	if _, ok := clusterInfo[masterClusterName]; !ok {
		panic("Master cluster is not specified in cluster info")

View on GitHub (pinned to bde624efd1)

Solutions

  1. Add at least the current cluster (and all replication clusters) to the clusterInfo passed to NewMetadata
  2. Verify the config file actually contains the clusters section and is being loaded from the right path
  3. Validate cluster config presence in a pre-start check before constructing metadata
  4. Check env-specific config overrides are not blanking out the clusters list

Example fix

// before (config.yaml)
clusterMetadata:
  enableGlobalDomain: true
  # clusters section missing
// after (config.yaml)
clusterMetadata:
  enableGlobalDomain: true
  clusters:
    - clusterName: active
      clusterAddress: "127.0.0.1:7233"
      failoverVersionIncrement: 10
      initialFailoverVersion: 0
Defensive patterns

Strategy: validation

Validate before calling

if len(clusterInfo) == 0 {
    return errors.New("config error: clusterInformation must define at least one cluster")
}

Type guard

func hasClusters(info map[string]cluster.ClusterInformation) bool { return len(info) > 0 }

Prevention

When it happens

Trigger: Calling NewMetadata with clusterInfo == nil or an empty map — e.g. an empty `clusters:` section in the config, all clusters filtered out by env-specific config loading, or a config struct that failed to populate.

Common situations: Frontend/history service config missing the `system.clusterInformation`/clusters block; misread or wrong config file path yielding defaults; config parsing that silently drops entries with bad keys; automated config generation producing an empty cluster list.

Related errors


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/211d17d1e7bdf8d2. Report an issue: GitHub.