hashicorp/consul · error

all indexers must have a non-empty name

Error message

all indexers must have a non-empty name

What it means

index.New builds a cache index for Consul's resource controller framework. The index name is mandatory: it becomes the key used to register and later query the index in the controller cache. An empty name is a programming error rejected immediately with a panic at construction time, so the failure surfaces during controller setup rather than as a silent cache miss later.

Source

Thrown at internal/controller/cache/index/index.go:19

// Copyright IBM Corp. 2024, 2026
// SPDX-License-Identifier: BUSL-1.1

package index

import (
	"github.com/hashicorp/consul/proto-public/pbresource"
	iradix "github.com/hashicorp/go-immutable-radix/v2"
)

type Index struct {
	name     string
	required bool
	indexer  MultiIndexer
}

func New(name string, i Indexer, opts ...IndexOption) *Index {
	if name == "" {
		panic("all indexers must have a non-empty name")
	}
	if i == nil {
		panic("no indexer was supplied when creating a new cache Index")
	}

	var multiIndexer MultiIndexer
	switch v := i.(type) {
	case SingleIndexer:
		multiIndexer = singleIndexWrapper{indexer: v}
	case MultiIndexer:
		multiIndexer = v
	default:
		panic("The Indexer must also implement one of the SingleIndexer or MultiIndexer interfaces")
	}

	idx := &Index{
		name:    name,
		indexer: multiIndexer,

View on GitHub (pinned to 2397ff0d76)

Solutions

  1. Pass a non-empty, descriptive, unique name, e.g. index.New("kind", indexer)
  2. If names are generated, default them when empty: if name == "" { name = kind + "-default" }
  3. Add a startup test asserting every index handed to WithWatch has a non-empty name

Example fix

// before
idx := index.New("", indexer) // panic: all indexers must have a non-empty name

// after
idx := index.New("kind", indexer)
Defensive patterns

Strategy: validation

Validate before calling

// validate index definitions before controller construction
func assertIndexNames(idxs []*index.Index) error {
    for _, i := range idxs {
        if i == nil || i.String() == "" { // i.String() returns the name
            return fmt.Errorf("all indexes must have non-empty names")
        }
    }
    return nil
}

Prevention

When it happens

Trigger: Calling index.New("", indexer) — usually a name built dynamically from a variable or config field that was never set, a loop variable that ended up empty, or a refactoring that dropped the literal.

Common situations: Generating index definitions from external config where the name field is optional; refactoring index registration code; copy-pasting an index definition and forgetting to change the name.

Related errors


AI-assisted analysis of hashicorp/consul@2397ff0d76 (2026-08-15). Data as JSON: /api/errors/1530984184fea9fa. Report an issue: GitHub.