openimsdk/open-im-server · error

ReqIdentifier failed,sendID:%s,msgIncr:%s,reqIdentifier:%d

Error message

ReqIdentifier failed,sendID:%s,msgIncr:%s,reqIdentifier:%d

What it means

The WebSocket gateway's handleMessage dispatches on the request's ReqIdentifier. If the identifier matches none of the known message types (WsLogin, WsLogout, WsSendMessage, etc.), the default branch returns this error carrying sendID, msgIncr and the raw identifier so the sender can correlate the failure. The client sent a protocol operation the server does not implement (or a corrupt/garbage identifier).

Source

Thrown at internal/msggateway/client.go:205

		resp, messageErr = c.longConnServer.SendMessage(ctx, binaryReq)
	case WSSendSignalMsg:
		resp, messageErr = c.longConnServer.SendSignalMessage(ctx, binaryReq)
	case WSPullMsgBySeqList:
		resp, messageErr = c.longConnServer.PullMessageBySeqList(ctx, binaryReq)
	case WSPullMsg:
		resp, messageErr = c.longConnServer.GetSeqMessage(ctx, binaryReq)
	case WSGetConvMaxReadSeq:
		resp, messageErr = c.longConnServer.GetConversationsHasReadAndMaxSeq(ctx, binaryReq)
	case WsPullConvLastMessage:
		resp, messageErr = c.longConnServer.GetLastMessage(ctx, binaryReq)
	case WsLogoutMsg:
		resp, messageErr = c.longConnServer.UserLogout(ctx, binaryReq)
	case WsSetBackgroundStatus:
		resp, messageErr = c.setAppBackgroundStatus(ctx, binaryReq)
	case WsSubUserOnlineStatus:
		resp, messageErr = c.longConnServer.SubUserOnlineStatus(ctx, c, binaryReq)
	default:
		return fmt.Errorf(
			"ReqIdentifier failed,sendID:%s,msgIncr:%s,reqIdentifier:%d",
			binaryReq.SendID,
			binaryReq.MsgIncr,
			binaryReq.ReqIdentifier,
		)
	}

	return c.replyMessage(ctx, binaryReq, messageErr, resp)
}

func (c *Client) setAppBackgroundStatus(ctx context.Context, req *Req) ([]byte, error) {
	resp, isBackground, messageErr := c.longConnServer.SetUserDeviceBackground(ctx, req)
	if messageErr != nil {
		return nil, messageErr
	}

	c.IsBackground = isBackground
	// TODO: callback

View on GitHub (pinned to 175a7bb067)

Solutions

  1. Upgrade the client SDK to a version matching the server's protocol constants
  2. Log the failing ReqIdentifier value and check it against the gateway's Ws* constants in the protocol package
  3. Fix the client's message encoding (ensure binary frames with correct field order/endian)
  4. If intentionally adding a new op, implement its case in handleMessage

Example fix

// before
conn.WriteJSON(map[string]interface{}{"reqIdentifier": 999}) // unsupported on server
// after
req := sdkwsReq{ReqIdentifier: wsProtocol.WsSendMessage, ...}
conn.WriteMessage(websocket.BinaryMessage, protoMarshal(req))
Defensive patterns

Strategy: type-guard

Validate before calling

known := map[int32]bool{wsProtocol.WsLogin: true, wsProtocol.WsLogout: true, wsProtocol.WsSendMessage: true, wsProtocol.WsSubUserOnlineStatus: true}
if !known[int32(req.ReqIdentifier)] {
	// reject before sending
}

Type guard

func isKnownReqIdentifier(id int32) bool {
	switch id {
	case WsLogin, WsLogout, WsSendMessage, WsKickOnline, WsSubUserOnlineStatus, WsSetBackgroundStatus:
		return true
	}
	return false
}

Try / catch

if err := c.handleMessage(ctx, binaryReq); err != nil {
	if strings.Contains(err.Error(), "ReqIdentifier failed") {
		log.ZWarn(ctx, "unsupported req identifier, check client/server protocol version", err, "reqIdentifier", binaryReq.ReqIdentifier)
		c.sendErrMsg(binaryReq, err)
		return
	}
}

Prevention

When it happens

Trigger: A client sends a WS binary frame whose ReqIdentifier value is not one of the gateway's supported constants (wrong SDK version, hand-rolled client, corrupted frame, or endian/serialization mismatch).

Common situations: Custom/older SDK talking to a newer gateway; a client sending text instead of the expected binary protocol; protocol constants changed between server versions; fuzzer or security scanner hitting the WS endpoint.

Related errors


AI-assisted analysis of openimsdk/open-im-server@175a7bb067 (2026-09-04). Data as JSON: /api/errors/e14fc1eff33f6cc1. Report an issue: GitHub.