XTLS/Xray-core · error · errors.Error
failed to get handler:
Error message
failed to get handler:
What it means
Returned by handlerServer.AlterInbound (app/proxyman/command/command.go:97) when inbound.Manager.GetHandler cannot find a handler registered under request.Tag. The inbound manager keeps handlers keyed by tag; unknown tag means either the inbound was never added, was removed, or the tag string does not match exactly (tags are case-sensitive).
Source
Thrown at app/proxyman/command/command.go:97
}
func (s *handlerServer) RemoveInbound(ctx context.Context, request *RemoveInboundRequest) (*RemoveInboundResponse, error) {
return &RemoveInboundResponse{}, s.ihm.RemoveHandler(ctx, request.Tag)
}
func (s *handlerServer) AlterInbound(ctx context.Context, request *AlterInboundRequest) (*AlterInboundResponse, error) {
rawOperation, err := request.Operation.GetInstance()
if err != nil {
return nil, errors.New("unknown operation").Base(err)
}
operation, ok := rawOperation.(InboundOperation)
if !ok {
return nil, errors.New("not an inbound operation")
}
handler, err := s.ihm.GetHandler(ctx, request.Tag)
if err != nil {
return nil, errors.New("failed to get handler: ", request.Tag).Base(err)
}
return &AlterInboundResponse{}, operation.ApplyInbound(ctx, handler)
}
func (s *handlerServer) ListInbounds(ctx context.Context, request *ListInboundsRequest) (*ListInboundsResponse, error) {
handlers := s.ihm.ListHandlers(ctx)
response := &ListInboundsResponse{}
if request.GetIsOnlyTags() {
for _, handler := range handlers {
response.Inbounds = append(response.Inbounds, &core.InboundHandlerConfig{
Tag: handler.Tag(),
})
}
} else {
for _, handler := range handlers {
response.Inbounds = append(response.Inbounds, &core.InboundHandlerConfig{
Tag: handler.Tag(),View on GitHub (pinned to 7d214f8b09)
Solutions
- List existing inbounds with ListInbounds and copy the exact tag.
- Ensure the tag references an inbound, not an outbound.
- If inbounds are managed dynamically, re-add the handler before altering it.
- Trim whitespace and match case exactly.
Example fix
// before
req := &AlterInboundRequest{Tag: "VLESS-IN"}
// after — exact tag from config/list
req := &AlterInboundRequest{Tag: "vless-in"} Defensive patterns
Strategy: validation
Validate before calling
// verify the tag exists before altering
resp, _ := client.ListInbounds(ctx, &command.ListInboundsRequest{})
known := map[string]bool{}
for _, in := range resp.Inbounds { known[in.Tag] = true }
if !known[request.Tag] { return fmt.Errorf("unknown inbound tag %q", request.Tag) } Try / catch
if err != nil && strings.Contains(err.Error(), "failed to get handler") {
return fmt.Errorf("inbound %q not found; check ListInbounds", request.Tag)
} Prevention
- Always derive tags from ListInbounds rather than hardcoding.
- Tags are case-sensitive; avoid trailing spaces in JSON.
When it happens
Trigger: Calling AlterInbound with a tag that does not exist in the running instance: typo, case mismatch, tag of an outbound instead of an inbound, or the inbound was dynamically removed before the call.
Common situations: Panel/automation tools reusing stale tags after config reloads; referencing an outbound tag where an inbound tag was meant; whitespace accidentally included in the tag string.
Related errors
- can't get inbound proxy from handler.
- metrics must have a tag or listen address
- Cannot get depended features
- Cannot get depended features
- proxy is not a UserManager
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/b025e4fb268f0c58.
Report an issue: GitHub.