{"record":{"id":"2aa7bb47bffb69d7","repo":"OpenNHP/opennhp","slug":"plugin-not-implemented","errorCode":null,"errorMessage":"plugin not implemented","messagePattern":"plugin not implemented","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"nhp/plugins/serverpluginhandler.go","lineNumber":43,"sourceCode":"\tListService(*common.NhpListRequest, *NhpServerPluginHelper) (*common.ServerListResultMsg, error)\n\tAuthWithNHP(*common.NhpAuthRequest, *NhpServerPluginHelper) (*common.ServerKnockAckMsg, error)\n\tAuthWithHttp(*gin.Context, *common.HttpKnockRequest, *HttpServerPluginHelper) (*common.ServerKnockAckMsg, error)\n}\n\ntype PluginHandlerSymbol struct {\n\tsVersion       plugin.Symbol\n\tsSignature     plugin.Symbol\n\tsExportedData  plugin.Symbol\n\tsInit          plugin.Symbol\n\tsClose         plugin.Symbol\n\tsRequestOTP    plugin.Symbol\n\tsRegisterAgent plugin.Symbol\n\tsListService   plugin.Symbol\n\tsAuthWithNHP   plugin.Symbol\n\tsAuthWithHttp  plugin.Symbol\n}\n\nvar errPluginNotImplemented error = fmt.Errorf(\"plugin not implemented\")\n\nfunc (s *PluginHandlerSymbol) Version() string {\n\tif s.sVersion == nil {\n\t\treturn \"\"\n\t}\n\tdefer utils.CatchPanic()\n\n\treturn s.sVersion.(func() string)()\n}\n\nfunc (s *PluginHandlerSymbol) Signature() string {\n\tif s.sSignature == nil {\n\t\treturn \"\"\n\t}\n\tdefer utils.CatchPanic()\n\n\treturn s.sSignature.(func() string)()\n}","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/nhp/plugins/serverpluginhandler.go#L25-L61","documentation":"PluginHandlerSymbol is the placeholder returned when no real server plugin (.so) is loaded; every PluginHandler method checks whether the corresponding dlopen symbol was resolved and returns errPluginNotImplemented if it was not. It signals that the handler is a stub and the requested plugin operation (Init, Close, RequestOTP, RegisterAgent, ListService, AuthWithNHP) has no backing implementation.","triggerScenarios":"The server was configured without a valid plugin path, the .so failed to load (wrong ABI, missing dependency), or openplugin returned a stub handler; the server then calls RegisterAgent, AuthWithNHP, ListService, RequestOTP, Init, or Close on that stub.","commonSituations":"Running nhp-serverd without building/loading the example server plugin; plugin .so built against a different Go version so symbols fail to resolve; typo in plugin config path so the fallback symbol handler is used.","solutions":["Check the server's plugin configuration (plugin .so path) and ensure the plugin file exists and is loadable","Rebuild the plugin with the same Go version as the server binary (go build -buildmode=plugin) and redeploy it","Confirm plugin loading succeeded at startup by checking the dlopen/openplugin step and its logs before treating handler method failures as plugin bugs"],"exampleFix":"// before (config.toml)\n# [plugin] section missing\n// after\n[plugin]\npath = \"plugins/server-plugin.so\"","handlingStrategy":"validation","validationCode":"h := plugins.GetHandler()\nif _, ok := h.(*plugins.PluginHandlerSymbol); ok {\n    return errors.New(\"no server plugin loaded; check plugin config\")\n}","typeGuard":null,"tryCatchPattern":"if err := h.AuthWithNHP(in); err != nil {\n    if errors.Is(err, plugins.ErrPluginNotImplemented) || err.Error() == \"plugin not implemented\" {\n        return fmt.Errorf(\"plugin missing: %w\", err)\n    }\n    return err\n}","preventionTips":["Verify the plugin .so loads at startup and log a fatal error if it does not","Build the plugin with the exact same Go toolchain version as the daemon","Add a startup smoke test calling h.Version() and failing if it returns an empty string","Keep the plugin path in config under health checks"],"tags":["go","plugins","stub","configuration"],"backgroundTag":"method-not-implemented","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}