vitessio/vitess · error

unregistered Authenticator implementation

Error message

unregistered Authenticator implementation

What it means

ErrUnregisteredAuthenticationImpl is returned by rbac.Reify when the RBAC config names an authenticator that was never registered via RegisterAuthenticator. The package keeps a registry map of name-to-constructor pairs; Reify looks up the configured name and fails if it is absent. This is a configuration error, not a runtime failure of the authenticator itself.

Source

Thrown at go/vt/vtadmin/rbac/authentication.go:125

	}

	return context.WithValue(ctx, actorkey{}, actor)
}

// FromContext extracts an actor from the context, if one exists.
func FromContext(ctx context.Context) (*Actor, bool) {
	actor, ok := ctx.Value(actorkey{}).(*Actor)
	if !ok {
		return nil, false
	}

	return actor, true
}

var (
	// ErrUnregisteredAuthenticationImpl is returned when an RBAC config
	// specifies an authenticator name that was not registered.
	ErrUnregisteredAuthenticationImpl = errors.New("unregistered Authenticator implementation")
	authenticators                    = map[string]func() Authenticator{}
	authenticatorsM                   sync.Mutex
)

// RegisterAuthenticator registers an authenticator implementation by name. It
// is not safe for concurrent use.
//
// Plugin-based authenticators are loaded separately, and need not call this
// function.
func RegisterAuthenticator(name string, f func() Authenticator) {
	if _, ok := authenticators[name]; ok {
		panic("authenticator already registered with name: " + name)
	}

	authenticators[name] = f
}

func loadAuthenticatorPlugin(path string) (Authenticator, error) {

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the configured authenticator name against the names actually passed to rbac.RegisterAuthenticator in the vtadmin build you run
  2. Register a custom implementation: call rbac.RegisterAuthenticator("yourname", func() rbac.Authenticator { return yourAuth }) before Reify
  3. Use a registered authenticator name (e.g. the default) in the RBAC config

Example fix

// before (config)
{"authenticators": ["Auth0Auth"]}
// after — register it before Reify
rbac.RegisterAuthenticator("Auth0Auth", func() rbac.Authenticator { return &MyAuth{} })
rbac.Reify(config)
Defensive patterns

Strategy: validation

Validate before calling

// before Reify
rbac.RegisterAuthenticator("Auth0Auth", func() rbac.Authenticator { return &MyAuth{} })
if cfg.Authenticator != "" && !rbac.IsAuthenticatorRegistered(cfg.Authenticator) { /* fix config */ }

Type guard

func authenticatorRegistered(name string) bool {
    _, ok := knownAuthenticators[name]
    return ok
}

Try / catch

actor, err := rc.Reify()
if err != nil {
    if errors.Is(err, rbac.ErrUnregisteredAuthenticationImpl) {
        log.Fatalf("RBAC config names an unregistered authenticator: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Setting `authenticators: ["SomeAuth"]` (or similar) in the vtadmin RBAC config where "SomeAuth" was never passed to RegisterAuthenticator before Reify is called; typo in the authenticator name; registering the authenticator in a different binary or after Reify runs.

Common situations: Copy-pasting vtadmin RBAC config from another deployment with custom authenticators compiled in; renaming an authenticator during a version upgrade; expecting a built-in authenticator to exist that is only registered by a specific build.

Understand the failure class

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/a7cd26bb558e73da. Report an issue: GitHub.