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

  1. List existing inbounds with ListInbounds and copy the exact tag.
  2. Ensure the tag references an inbound, not an outbound.
  3. If inbounds are managed dynamically, re-add the handler before altering it.
  4. 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

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


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/b025e4fb268f0c58. Report an issue: GitHub.