{"record":{"id":"e2f221872d08212f","repo":"MHSanaei/3x-ui","slug":"remote-inbound-with-tag-q-not-found-on-node-s","errorCode":null,"errorMessage":"remote inbound with tag %q not found on node %s","messagePattern":"remote inbound with tag %q not found on node (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/web/runtime/remote.go","lineNumber":304,"sourceCode":"\t\treturn nil, fmt.Errorf(\"decode envelope: %w\", err)\n\t}\n\tif !env.Success {\n\t\treturn &env, &remoteAPIError{msg: env.Msg}\n\t}\n\treturn &env, nil\n}\n\nfunc (r *Remote) resolveRemoteID(ctx context.Context, tag string) (int, error) {\n\tif id, ok := r.cacheGetTag(tag); ok {\n\t\treturn id, nil\n\t}\n\tif err := r.refreshRemoteIDs(ctx); err != nil {\n\t\treturn 0, err\n\t}\n\tif id, ok := r.cacheGetTag(tag); ok {\n\t\treturn id, nil\n\t}\n\treturn 0, fmt.Errorf(\"remote inbound with tag %q not found on node %s\", tag, r.node.Name)\n}\n\n// nodeInboundTagPrefix is the central-panel alias for an inbound on nodeID.\n// Kept in sync with service.nodeTagPrefix (port_conflict.go); duplicated here\n// so runtime does not import service.\nfunc nodeInboundTagPrefix(nodeID int) string {\n\treturn fmt.Sprintf(\"n%d-\", nodeID)\n}\n\n// stripNodeInboundTagPrefix removes the central-only n<id>- prefix before\n// pushing an inbound to the node so Xray keeps its original tag and routing.\nfunc stripNodeInboundTagPrefix(nodeID int, tag string) string {\n\tif stripped, ok := strings.CutPrefix(tag, nodeInboundTagPrefix(nodeID)); ok {\n\t\treturn stripped\n\t}\n\treturn tag\n}\n","sourceCodeStart":286,"sourceCodeEnd":322,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/web/runtime/remote.go#L286-L322","documentation":"Thrown by Remote.resolveRemoteID when an inbound tag known centrally has no counterpart on the node, even after a fresh refreshRemoteIDs() pull of the node's inbound list. The runtime needs the node-local numeric inbound ID to address per-client RPCs (add/detach), and tag-to-ID resolution failed. It almost always means central and node disagree about which inbounds exist.","triggerScenarios":"AddClient/DeleteUser for an inbound whose tag is absent on the node: the inbound was deleted or renamed directly on the node, the node DB was reset/re-imported, an out-of-band Xray config edit changed tags, or a partial earlier push never created the inbound on the node.","commonSituations":"Someone edited inbounds on the node's own panel instead of the master; node restored from an old backup; central tag n<id>- prefix stripped inconsistently; failed initial push left central thinking the inbound exists remotely.","solutions":["Open the node's own panel and check whether the inbound (with the un-prefixed tag) exists; recreate it if it was deleted out-of-band.","Trigger a full inbound push/reconcile from the master (save the inbound or run ReconcileNode) so the node gets the missing inbound before per-client ops run.","Stop editing node-side inbounds directly — manage node-assigned inbounds only through the central panel.","If tags drifted, rename on the node back to what the central settings JSON expects."],"exampleFix":"// before: inbound \"n3-vless-443\" exists centrally but node has \"vless-8443\" (renamed locally)\n// err: remote inbound with tag \"n3-vless-443\" not found on node edge-1\n\n// after: on the node, rename the inbound back to vless-443 (or re-save the inbound on the master to force a fresh push) -> resolveRemoteID succeeds","handlingStrategy":"validation","validationCode":"// Verify tag parity before per-client writes\nids, err := remote.ListInboundTags(ctx)\nif err != nil { return err }\nif !slices.Contains(ids, stripNodeInboundTagPrefix(nodeID, ib.Tag)) {\n    return fmt.Errorf(\"tag %s missing on node; push the inbound first\", ib.Tag)\n}","typeGuard":"func isTagNotFound(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"not found on node\")\n}","tryCatchPattern":"if err := remote.AddClient(ctx, ib, client); err != nil {\n    if isTagNotFound(err) {\n        return pushInboundThenRetry(ctx, ib, client) // converge then retry once\n    }\n    return err\n}","preventionTips":["Manage node-assigned inbounds ONLY from the central panel.","After any node restore/backup, run a reconcile to re-sync tag maps before client ops.","Alert on tag-resolution failures — they signal central/node drift that reconcile should fix."],"tags":["node-sync","tag-mismatch","runtime","remote","reconcile"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}