MHSanaei/3x-ui · error
remote inbound with tag %q not found on node %s
Error message
remote inbound with tag %q not found on node %s
What it means
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.
Source
Thrown at internal/web/runtime/remote.go:304
return nil, fmt.Errorf("decode envelope: %w", err)
}
if !env.Success {
return &env, &remoteAPIError{msg: env.Msg}
}
return &env, nil
}
func (r *Remote) resolveRemoteID(ctx context.Context, tag string) (int, error) {
if id, ok := r.cacheGetTag(tag); ok {
return id, nil
}
if err := r.refreshRemoteIDs(ctx); err != nil {
return 0, err
}
if id, ok := r.cacheGetTag(tag); ok {
return id, nil
}
return 0, fmt.Errorf("remote inbound with tag %q not found on node %s", tag, r.node.Name)
}
// nodeInboundTagPrefix is the central-panel alias for an inbound on nodeID.
// Kept in sync with service.nodeTagPrefix (port_conflict.go); duplicated here
// so runtime does not import service.
func nodeInboundTagPrefix(nodeID int) string {
return fmt.Sprintf("n%d-", nodeID)
}
// stripNodeInboundTagPrefix removes the central-only n<id>- prefix before
// pushing an inbound to the node so Xray keeps its original tag and routing.
func stripNodeInboundTagPrefix(nodeID int, tag string) string {
if stripped, ok := strings.CutPrefix(tag, nodeInboundTagPrefix(nodeID)); ok {
return stripped
}
return tag
}
View on GitHub (pinned to ad32144c42)
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.
Example fix
// before: inbound "n3-vless-443" exists centrally but node has "vless-8443" (renamed locally) // err: remote inbound with tag "n3-vless-443" not found on node edge-1 // 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
Defensive patterns
Strategy: validation
Validate before calling
// Verify tag parity before per-client writes
ids, err := remote.ListInboundTags(ctx)
if err != nil { return err }
if !slices.Contains(ids, stripNodeInboundTagPrefix(nodeID, ib.Tag)) {
return fmt.Errorf("tag %s missing on node; push the inbound first", ib.Tag)
} Type guard
func isTagNotFound(err error) bool {
return err != nil && strings.Contains(err.Error(), "not found on node")
} Try / catch
if err := remote.AddClient(ctx, ib, client); err != nil {
if isTagNotFound(err) {
return pushInboundThenRetry(ctx, ib, client) // converge then retry once
}
return err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- %s %s: %w
- remote AddClient: resolve tag %q: %w
- remote DeleteUser: resolve tag %q: %w
- %s %s: HTTP %d: %q
- %s %s: HTTP %d
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/e2f221872d08212f.
Report an issue: GitHub.