vitessio/vitess · error

invalid parameter Number from client %v, statement: %v

Error message

invalid parameter Number from client %v, statement: %v

What it means

This error is returned when a MySQL client sends COM_STMT_SEND_LONG_DATA referencing a statement parameter ID that does not exist in the prepared statement (i.e., paramID >= number of declared parameters). The server rejects the packet and replies with an error packet to the client. It protects the protocol state from malformed or out-of-sync client packets.

Source

Thrown at go/mysql/conn.go:1315

func (c *Conn) handleComStmtSendLongData(data []byte) bool {
	stmtID, paramID, chunk, ok := c.parseComStmtSendLongData(data)
	c.recycleReadPacket()
	if !ok {
		err := fmt.Errorf("error parsing statement send long data from client %v, returning error: %v", c.ConnectionID, data)
		return c.writeErrorPacketFromErrorAndLog(err)
	}

	prepare, ok := c.PrepareData[stmtID]
	if !ok {
		err := fmt.Errorf("got wrong statement id from client %v, statement ID(%v) is not found from record", c.ConnectionID, stmtID)
		return c.writeErrorPacketFromErrorAndLog(err)
	}

	if prepare.BindVars == nil ||
		prepare.ParamsCount == uint16(0) ||
		paramID >= prepare.ParamsCount {
		err := fmt.Errorf("invalid parameter Number from client %v, statement: %v", c.ConnectionID, prepare.PrepareStmt)
		return c.writeErrorPacketFromErrorAndLog(err)
	}

	// COM_STMT_SEND_LONG_DATA is preparatory state for a later COM_STMT_EXECUTE,
	// not a separately logged query. Hold its ingress bytes so COM_STMT_EXECUTE
	// accounts for the full client payload used to run the statement.
	if c.pendingLongDataIngressBytes == nil {
		c.pendingLongDataIngressBytes = make(map[uint32]uint64)
	}
	c.pendingLongDataIngressBytes[stmtID] += c.currentCommandIngressBytes

	key := fmt.Sprintf("v%d", paramID+1)
	if val, ok := prepare.BindVars[key]; ok {
		val.Value = append(val.Value, chunk...)
	} else {
		prepare.BindVars[key] = sqltypes.BytesBindVariable(chunk)
	}
	return true

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the client's statement SQL and confirm the number of `?` placeholders matches the highest parameter index the client sends long data for.
  2. Ensure COM_STMT_PREPARE succeeded before sending COM_STMT_SEND_LONG_DATA, and that COM_STMT_CLOSE has not been issued.
  3. Update or fix the client driver/library — modern mysql clients (go-sql-driver, Connector/J, etc.) compute param IDs correctly.
  4. If a proxy is in the path, verify it forwards COM_STMT_SEND_LONG_DATA for the correct statement handle without rewriting param IDs.

Example fix

// before: sending long data for an unknown param index
// stmt has 2 placeholders, client sends paramID 2
sendLongData(stmtID, paramID=2, data)

// after: align client params with the prepared statement
// SELECT ? , ? -> valid paramIDs are 0 and 1
sendLongData(stmtID, paramID=1, data)
Defensive patterns

Strategy: validation

Validate before calling

// client side, before COM_STMT_SEND_LONG_DATA
if paramID < 0 || paramID >= numPlaceholders(stmtSQL) {
    return fmt.Errorf("param %d out of range for statement with %d placeholders", paramID, numPlaceholders(stmtSQL))
}

Try / catch

// server/driver side
if err := conn.Exec(stmt); err != nil {
    if strings.Contains(err.Error(), "invalid parameter Number from client") {
        // re-prepare the statement and rebind params before retrying
        stmt, err = conn.Prepare(stmtSQL)
    }
}

Prevention

When it happens

Trigger: A client issues COM_STMT_SEND_LONG_DATA for a statement whose `prepare.BindVars` is nil or whose parameter index is >= `prepare.ParamsCount` — e.g. sending long data for param 3 on a statement prepared with only 2 placeholders, or sending long data after the statement was deallocated.

Common situations: Buggy or hand-rolled client drivers mishandling prepared-statement parameter numbering; client/server placeholder-count mismatch after application queries changed; stale connection reuse where the client thinks a statement is still prepared; proxies or load balancers desynchronizing COM_STMT_* streams.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/b0eafffc78fb8656. Report an issue: GitHub.