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
- Implement every method of the plugins.PluginHandler interface on the handler type
- Rebuild the plugin .so against the same opennhp version/interface as the running serverd
- Pass a non-nil handler; check the plugin load step for errors before LoadPlugin
- 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
- Add a compile-time assertion `var _ plugins.PluginHandler = (*T)(nil)` to every plugin
- Build plugins from the same commit/tag as the running serverd
- Test plugin loading in CI before deploying
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
- cluster : missing publicKeyBase64
- cluster ( ): no instances configured
- cluster instance # : must set either Host or Ip
- cluster instance # : invalid port
- AuthServiceId is required
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)