hashicorp/consul · error

no indexer was supplied when creating a new cache Index

Error message

no indexer was supplied when creating a new cache Index

What it means

index.New requires both a name and an actual Indexer implementation. Passing a nil Indexer panics at construction: a named index with nothing to compute it would silently produce empty query results, so the constructor fails fast. Note the check only catches an untyped nil interface — a typed nil pointer stored in the interface passes here and typically blows up later in the type switch or at query time.

Source

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

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,
	}

	for _, opt := range opts {

View on GitHub (pinned to 2397ff0d76)

Solutions

  1. Construct and pass a real indexer implementation (SingleIndexer or MultiIndexer)
  2. If a helper may produce nil, check before calling New: if idxr == nil { return errors.New("indexer required") }
  3. Construct indexes unconditionally at controller setup rather than leaving a declared-but-nil variable

Example fix

// before
var indexer index.SingleIndexer
// ... branch forgot to assign indexer
idx := index.New("kind", indexer) // panic: no indexer was supplied

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

Strategy: validation

Validate before calling

// check the interface variable before constructing the Index
func buildIndex(name string, idxr index.Indexer) (*index.Index, error) {
    if idxr == nil {
        return nil, fmt.Errorf("index %q: indexer must not be nil", name)
    }
    return index.New(name, idxr), nil
}

Type guard

// catches typed-nil pointers stored in the interface too
func isNilIndexer(i index.Indexer) bool {
    if i == nil {
        return true
    }
    v := reflect.ValueOf(i)
    return v.Kind() == reflect.Ptr && v.IsNil()
}

Prevention

When it happens

Trigger: Calling index.New("name", nil), or passing an indexer variable that was declared but never assigned, or one returned as nil by a constructor function that swallowed an error.

Common situations: Index construction refactored into helper functions that can return nil; building indexes conditionally where some branch forgets to assign; partially completed migrations to the controller framework.

Related errors


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