v2rayA/v2rayA · error
tag '%s' already exists
Error message
tag '%s' already exists
What it means
PostCustomInbound rejects creation of a custom inbound whose Tag matches an existing inbound's tag. Tags are unique identifiers used by the core to reference inbounds, so duplicates would create ambiguous references. The check iterates all configured custom inbounds before saving.
Source
Thrown at service/server/controller/customInbound.go:92
hardcodeReplacement := regexp.MustCompile(`\$\$.+?\$\$`)
for i := range lines {
hardcodes := hardcodeReplacement.FindAllString(lines[i], -1)
for _, hardcode := range hardcodes {
lines[i] = strings.Replace(lines[i], hardcode, "", 1)
}
}
_, err := RoutingA.Parse(strings.Join(lines, "\n"))
if err != nil {
common.ResponseError(ctx, logError(fmt.Errorf("invalid RoutingA rules: %w", err)))
return
}
}
inbounds := configure.GetCustomInbounds()
// check duplicate tag and port
for _, existing := range inbounds {
if existing.Tag == ci.Tag {
common.ResponseError(ctx, logError(fmt.Errorf("tag '%s' already exists", ci.Tag)))
return
}
if existing.Port == ci.Port {
common.ResponseError(ctx, logError(fmt.Errorf("port %d is already in use by '%s'", ci.Port, existing.Tag)))
return
}
}
inbounds = append(inbounds, ci)
if err := configure.SetCustomInbounds(inbounds); err != nil {
common.ResponseError(ctx, logError(err))
return
}
common.ResponseSuccess(ctx, gin.H{"inbounds": inbounds})
}
func DeleteCustomInbound(ctx *gin.Context) {
var req struct {
Tag string `json:"tag"`View on GitHub (pinned to 71e5442fc5)
Solutions
- Choose a different, unique tag for the new inbound
- List existing inbounds first and pick an unused tag
- Delete the old inbound with the same tag if it is no longer needed
- Make the client idempotent: check for existence before POSTing
Example fix
// before
{ "tag": "inbound-1", "port": 1080, ... }
// after
{ "tag": "inbound-2", "port": 1080, ... } Defensive patterns
Strategy: validation
Validate before calling
inbounds := configure.GetCustomInbounds()
if inbounds.Any(func(i configure.CustomInbound) bool { return i.Tag == newTag }) {
return fmt.Errorf("tag %q already exists", newTag)
} Prevention
- Generate unique tags programmatically (prefix + counter/uuid)
- List existing inbounds before creating
- Make client retries idempotent by checking existence first
When it happens
Trigger: POST to the custom inbound API with a 'tag' field identical to any existing custom inbound's tag.
Common situations: Re-submitting a form after a partial failure; client retry duplicating a successfully created inbound; copying an inbound definition and forgetting to change the tag.
Related errors
- duplicated inbound tag: %v
- duplicated outbound tag: %v
- invalid RoutingA rules: %w
- port %d is already in use by '%s'
- tuic: no UUID
AI-assisted analysis of v2rayA/v2rayA@71e5442fc5 (2026-09-05).
Data as JSON: /api/errors/173ee51c5d7a9aac.
Report an issue: GitHub.