{"record":{"id":"25fe92a651e04c56","repo":"XTLS/Xray-core","slug":"proxy-is-not-a-usermanager","errorCode":null,"errorMessage":"proxy is not a UserManager","messagePattern":"proxy is not a UserManager","errorType":"exception","errorClass":"errors.Error","httpStatus":null,"severity":"error","filePath":"app/proxyman/command/command.go","lineNumber":45,"sourceCode":"}\n\nfunc getInbound(handler inbound.Handler) (proxy.Inbound, error) {\n\tgi, ok := handler.(proxy.GetInbound)\n\tif !ok {\n\t\treturn nil, errors.New(\"can't get inbound proxy from handler.\")\n\t}\n\treturn gi.GetInbound(), nil\n}\n\n// ApplyInbound implements InboundOperation.\nfunc (op *AddUserOperation) ApplyInbound(ctx context.Context, handler inbound.Handler) error {\n\tp, err := getInbound(handler)\n\tif err != nil {\n\t\treturn err\n\t}\n\tum, ok := p.(proxy.UserManager)\n\tif !ok {\n\t\treturn errors.New(\"proxy is not a UserManager\")\n\t}\n\tmUser, err := op.User.ToMemoryUser()\n\tif err != nil {\n\t\treturn errors.New(\"failed to parse user\").Base(err)\n\t}\n\treturn um.AddUser(ctx, mUser)\n}\n\n// ApplyInbound implements InboundOperation.\nfunc (op *RemoveUserOperation) ApplyInbound(ctx context.Context, handler inbound.Handler) error {\n\tp, err := getInbound(handler)\n\tif err != nil {\n\t\treturn err\n\t}\n\tum, ok := p.(proxy.UserManager)\n\tif !ok {\n\t\treturn errors.New(\"proxy is not a UserManager\")\n\t}","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/app/proxyman/command/command.go#L27-L63","documentation":"Returned by AddUserOperation.ApplyInbound (app/proxyman/command/command.go:45) when the inbound handler's proxy does not implement proxy.UserManager. Only user-capable protocols (VMess, VLESS, Trojan, Shadowsocks, etc.) support runtime AddUser; protocol inbounds like dokodemo-door or a mis-tagged outbound-style handler reject user operations.","triggerScenarios":"Calling the HandlerService API's alterInbound with AddUserOperation for an inbound whose proxy type has no user concept — most often dokodemo-door, socks/http inbound (non-user-managed variants), or liberty/mixed handlers configured without user auth.","commonSituations":"Panels and automation tools that add users to whatever tag the operator typed; a typo in the tag resolving to the wrong inbound, or the panel assuming every inbound is a multi-user proxy.","solutions":["Target an inbound whose protocol supports users (vless/vmess/trojan/shadowsocks).","Verify the inbound tag with ListInbounds before issuing AddUser.","If you must add users dynamically, ensure the inbound was created through the API with the right settings."],"exampleFix":"// before — dokodemo-door cannot hold users\nreq := &ModifyInboundRequest{InboundTag: \"dokodemo-in\", Operation: addUserOp}\n\n// after — add to a VLESS inbound\nreq := &ModifyInboundRequest{InboundTag: \"vless-in\", Operation: addUserOp}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// check the inbound proxy supports users before AddUser\nif p, ok := handler.(proxy.GetInbound); ok {\n    if _, ok := p.GetInbound().(proxy.UserManager); ok {\n        // safe to add user\n    }\n}","tryCatchPattern":"if err := addOp.ApplyInbound(ctx, handler); err != nil {\n    if strings.Contains(err.Error(), \"not a UserManager\") { continue /* non-user inbound */ } else { return err }\n}","preventionTips":["Maintain a set of user-capable protocol names (vless, vmess, trojan, shadowsocks) and filter targets.","Validate inbound protocol from ListInbounds before user operations."],"tags":["go","xray","api","users","type-assertion"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}