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
- Use AddUserOperation/RemoveUserOperation (the currently defined inbound operations) with AlterInbound.
- Double-check the request type: outbound-directed operations go through AlterOutbound.
- 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
- Keep separate request builders for AlterInbound vs AlterOutbound.
- Custom operations must implement ApplyInbound to be usable on the inbound path.
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
- can't get inbound proxy from handler.
- proxy is not a UserManager
- unknown operation
- failed to parse user
- failed to get handler:
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/0dca82b10ef33f4f.
Report an issue: GitHub.