{"record":{"id":"f1a2f938c43adc3f","repo":"fatedier/frp","slug":"send-op-request-to-plugin-error","errorCode":null,"errorMessage":"send ${op} request to plugin error","messagePattern":"send (.+?) request to plugin error","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/plugin/server/manager.go","lineNumber":94,"sourceCode":"\tif len(plugins) == 0 {\n\t\treturn content, nil\n\t}\n\n\tvar (\n\t\tres = &Response{\n\t\t\tReject:   false,\n\t\t\tUnchange: true,\n\t\t}\n\t\tretContent any\n\t\terr        error\n\t)\n\tctx, xl := newPluginRequestContext()\n\n\tfor _, p := range plugins {\n\t\tres, retContent, err = p.Handle(ctx, op, *content)\n\t\tif err != nil {\n\t\t\tlogPluginError(xl, p, op, err, logMode)\n\t\t\treturn nil, errors.New(\"send \" + op + \" request to plugin error\")\n\t\t}\n\t\tif res.Reject {\n\t\t\treturn nil, fmt.Errorf(\"%s\", res.RejectReason)\n\t\t}\n\t\tif !res.Unchange {\n\t\t\t// Preserve the existing Plugin contract: changed content must be *T.\n\t\t\t// Buggy Plugin implementations still panic here, by design.\n\t\t\tcontent = retContent.(*T)\n\t\t}\n\t}\n\treturn content, nil\n}\n\nfunc (m *Manager) Register(p Plugin) {\n\tif p.IsSupport(OpLogin) {\n\t\tm.loginPlugins = append(m.loginPlugins, p)\n\t}\n\tif p.IsSupport(OpNewProxy) {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/plugin/server/manager.go#L76-L112","documentation":"Returned by plugin.Manager.Handle in frps when any plugin in the chain returns an error from its Handle call while processing an operation (e.g. NewProxy, UserConn, Ping). The underlying per-plugin error is logged (logPluginError) but the returned error is deliberately generic, so the real cause is only visible in frps logs.","triggerScenarios":"An HTTP plugin server configured in frps.toml [plugin.xxx] is unreachable, times out, or returns a malformed response; a built-in plugin (e.g. virtual_net) failing to initialize during the operation; plugin process crashing mid-request.","commonSituations":"Plugin HTTP server not started or wrong address/port in frps.toml; firewall blocking frps-to-plugin traffic; plugin response not matching the expected op schema; TLS mismatch between frps and the plugin endpoint.","solutions":["Check frps logs for the logPluginError line — it contains the actual underlying error for the specific plugin and op","Verify the plugin server is running and reachable at the configured addr from the frps host (curl the health/op endpoint)","Validate the plugin's response JSON matches the frp plugin protocol for the op being processed","If the error is transient (plugin restarting), ensure the plugin is healthy before clients reconnect"],"exampleFix":"# frps.toml — before\n[plugin.my-auth]\naddr = \"http://127.0.0.1:9000\"\nops = [\"Login\"]\n\n# after — point at the address the plugin actually listens on\n[plugin.my-auth]\naddr = \"http://10.0.0.5:9000\"\nops = [\"Login\"]","handlingStrategy":"try-catch","validationCode":"// Before enabling a plugin, probe its endpoint from the frps host\nresp, err := http.Get(pluginAddr + \"/health\") // or any documented route\nif err != nil || resp.StatusCode >= 500 {\n    // do not enable the plugin until it is healthy\n}","typeGuard":null,"tryCatchPattern":"// frps internal callers: capture the generic error, then consult logs\ncontent, err := pluginManager.Handle(ctx, op, content)\nif err != nil {\n    // underlying per-plugin error is in frps logs (logPluginError); match on op to triage\n    log.Warnf(\"plugin op %s failed: %v\", op, err)\n    return err\n}","preventionTips":["Run plugin health checks (or supervise the plugin process) so frps never routes ops to a dead plugin","Pin plugin protocol versions when upgrading frp; test Login/NewProxy ops against a staging frps first"],"tags":["frp","go","plugin","server","network"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}