XTLS/Xray-core · error · errors.Error

not an inbound operation

Error message

not an inbound operation

What it means

Returned by handlerServer.AlterInbound (app/proxyman/command/command.go:92) when the deserialized operation object does not implement the InboundOperation interface (ApplyInbound method). The type resolved successfully (error 54 did not fire) but it is not an inbound-side operation — e.g. an outbound operation was sent to AlterInbound.

Source

Thrown at app/proxyman/command/command.go:92

	if err := core.AddInboundHandler(s.s, request.Inbound); err != nil {
		return nil, err
	}

	return &AddInboundResponse{}, nil
}

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(),
			})

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Use AddUserOperation/RemoveUserOperation (the currently defined inbound operations) with AlterInbound.
  2. Double-check the request type: outbound-directed operations go through AlterOutbound.
  3. If defining custom operations, implement ApplyInbound(context.Context, inbound.Handler) error for inbound use.
Defensive patterns

Strategy: type-guard

Type guard

// client-side: ensure the payload is a known inbound operation before sending
func isInboundOperation(t string) bool {
    return t == "xray.app.proxyman.command.AddUserOperation" ||
           t == "xray.app.proxyman.command.RemoveUserOperation"
}

Try / catch

if err != nil && strings.Contains(err.Error(), "not an inbound operation") {
    return errors.New("sent an outbound/unknown operation to AlterInbound; fix request envelope")
}

Prevention

When it happens

Trigger: Sending an operation intended for AlterOutbound (or any random registered config type) in an AlterInboundRequest. The Any's type_url must reference a type implementing InboundOperation.

Common situations: API client bugs that mix up the inbound/outbound operation envelopes; future operation types that only implement ApplyOutbound.

Related errors


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