XTLS/Xray-core · error · errors.Error
unknown operation
Error message
unknown operation
What it means
Returned by handlerServer.AlterInbound (app/proxyman/command/command.go:88) when request.Operation.GetInstance() fails: the serialized Any operation message could not be turned into a concrete operation. Xray looks the operation type up in the global proto type registry; an unregistered or unknown type_url fails here.
Source
Thrown at app/proxyman/command/command.go:88
ohm outbound.Manager
}
func (s *handlerServer) AddInbound(ctx context.Context, request *AddInboundRequest) (*AddInboundResponse, error) {
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() {View on GitHub (pinned to 7d214f8b09)
Solutions
- Use serial.ToTypedMessage (Go) or the exact registered type URL when constructing the operation Any.
- Match client and server xray-core versions so all operation types exist on the server.
- Prefer the typed helpers (AddUserOperation/RemoveUserOperation) instead of hand-built Any payloads.
- Read the Base error to distinguish 'unknown type' from 'unmarshal failed'.
Example fix
// before
op := &anypb.Any{TypeUrl: "xray.app.proxyman.command.AddUserOperation", Value: arbitrary}
// after
addOp := &command.AddUserOperation{User: user}
op := serial.ToTypedMessage(addOp) Defensive patterns
Strategy: validation
Validate before calling
// confirm the operation type is registered before sending
if serial.MessageType((*command.AddUserOperation)(nil)) == "" {
return errors.New("AddUserOperation not registered in this build")
} Try / catch
resp, err := client.AlterInbound(ctx, req)
if err != nil && strings.Contains(err.Error(), "unknown operation") {
return fmt.Errorf("server build lacks this operation; upgrade server: %w", err)
} Prevention
- Build operation Any messages with typed helpers (serial.ToTypedMessage), never raw bytes.
- Pin matching xray-core versions on API client and server.
When it happens
Trigger: Sending an AlterInboundRequest whose Operation Any carries a type_url that was never registered (custom operation types not compiled into the binary), or a payload that fails to unmarshal. Also occurs with version mismatch: a newer client sending an operation type the older server build does not know.
Common situations: API clients built against different xray-core versions than the server; protobuf Any fields constructed by hand with the wrong type URL string (must match the registered proto name exactly).
Related errors
- not an inbound operation
- can't get inbound proxy from handler.
- proxy is not a UserManager
- failed to parse user
- failed to get handler:
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/313ebccb4ba8d422.
Report an issue: GitHub.