OpenNHP/opennhp · error

plugin validation failed

Error message

plugin validation failed

What it means

LoadPlugin runs UdpServer.ValidatePlugin on the provided plugins.PluginHandler before registering it; a handler missing required methods or returning false from validation is rejected and never added to pluginHandlerMap. This keeps half-implemented plugins from being invoked at request time.

Solutions

  1. Implement every method of the plugins.PluginHandler interface on the handler type
  2. Rebuild the plugin .so against the same opennhp version/interface as the running serverd
  3. Pass a non-nil handler; check the plugin load step for errors before LoadPlugin
  4. Compare the handler against examples/server_plugin for the expected method set

Example fix

// before
type myPlugin struct{} // missing AuthWithHttp
func (p *myPlugin) AuthWithNHP(...) {...}
// after — implement the full interface
type myPlugin struct{}
func (p *myPlugin) AuthWithNHP(...) {...}
func (p *myPlugin) AuthWithHttp(...) {...}
func (p *myPlugin) RegisterAgent(...) {...}
func (p *myPlugin) ListService(...) {...}
Defensive patterns

Strategy: type-guard

Validate before calling

var _ plugins.PluginHandler = (*MyPlugin)(nil) // compile-time interface check before LoadPlugin
if h == nil { return errors.New("plugin handler is nil") }
err := srv.LoadPlugin(pluginId, h)

Type guard

func implementsPluginHandler(h plugins.PluginHandler) bool { return h != nil }

Try / catch

if err := srv.LoadPlugin(id, h); err != nil {
    if strings.Contains(err.Error(), "validation failed") {
        log.Errorf("plugin %s does not implement PluginHandler fully: %v", id, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling UdpServer.LoadPlugin(pluginId, h) where h is nil or fails ValidatePlugin (e.g. missing required handler methods in a partially built Go plugin).

Common situations: Building a custom server plugin that doesn't implement the full PluginHandler interface (AuthWithNHP, AuthWithHttp, RegisterAgent, ListService, etc.); loading a .so compiled against a mismatched plugin API version; registering a nil handler when a plugin file failed to load.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07). Data as JSON: /api/errors/3214e326fe072452. Report an issue: GitHub.

Appendix: source

Thrown at endpoints/server/udpserver.go:1138

	s.authServiceMapMutex.Unlock()

	return nil
}

func (s *UdpServer) ValidatePlugin(h plugins.PluginHandler) bool {
	// placeholder to validate plugin file
	// err = checkSignature(s.Signature())
	// if err != nil {
	//   return false
	// }

	return true
}

func (s *UdpServer) LoadPlugin(pluginId string, h plugins.PluginHandler) error {
	if !s.ValidatePlugin(h) {
		log.Error("Plugin: %s validation failed", pluginId)
		return fmt.Errorf("plugin validation failed")
	}

	s.pluginHandlerMapMutex.Lock()
	oldHandler, found := s.pluginHandlerMap[pluginId]
	s.pluginHandlerMapMutex.Unlock()
	if found {
		oldHandler.Close()
	}

	pluginDirPath := filepath.Join(ExeDirPath, "plugins", pluginId)
	err := h.Init(&plugins.PluginParamsIn{
		PluginDirPath: &pluginDirPath,
		Log:           s.log.NewSubLogger("Plugin["+pluginId+"]", log.LogLevelDebug),
		Hostname:      &s.config.Hostname,
		LocalIp:       &s.localIp,
		LocalMac:      &s.localMac,
	})
	if err != nil {

View on GitHub (pinned to 6e04ca5ff0)