shadow1ng/fscan · warning

cassandra frame too large: %d

Error message

cassandra frame too large: %d

What it means

cqlRecv parsed the frame header and found a body length exceeding maxCQLFrameBody, the safety cap on Cassandra CQL frame sizes. It refuses to allocate/read the body and returns 'cassandra frame too large: %d' to protect against malicious or corrupt servers.

Source

Thrown at plugins/services/cassandra.go:206

	buf := append(header, body...)
	_, err := conn.Write(buf)
	return err
}

func cqlRecv(conn io.Reader) (byte, []byte, error) {
	// 读取 9 字节头部(响应也有额外标志字节)
	header := make([]byte, 9)
	if _, err := io.ReadFull(conn, header); err != nil {
		return 0, nil, err
	}
	opcode := header[4]
	bodyLen := int(binary.BigEndian.Uint32(header[5:9]))
	if bodyLen == 0 {
		return opcode, []byte{}, nil
	}
	if bodyLen > maxCQLFrameBody {
		return opcode, nil, fmt.Errorf("cassandra frame too large: %d", bodyLen)
	}
	body := make([]byte, bodyLen)
	if _, err := io.ReadFull(conn, body); err != nil {
		return opcode, nil, err
	}
	return opcode, body, nil
}

func validateCQLQueryResponse(opcode byte, body []byte) error {
	if opcode == cqlOpError {
		return fmt.Errorf("cassandra query failed: %s", string(body))
	}
	if opcode != cqlOpResult {
		return fmt.Errorf("unexpected query opcode: %d", opcode)
	}
	return nil
}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Verify the target is a genuine Cassandra node — a bogus huge length usually means the peer isn't speaking the CQL binary protocol.
  2. If legitimate responses are being rejected, raise maxCQLFrameBody to a value at or above the server's native_transport_frame_size/max frame size.
  3. Recover stream sync by reconnecting rather than continuing to read a desynchronized socket.

Example fix

// before
maxCQLFrameBody = 256 * 1024 // rejects large legit frames
// after
maxCQLFrameBody = 16 * 1024 * 1024 // matches server frame limit
Defensive patterns

Strategy: validation

Validate before calling

// server max frame size in cassandra.yaml must be <= client cap
// e.g. native_transport_max_frame_size_in_mb: 256
if serverMaxFrameMB*1024*1024 > maxCQLFrameBody {
    log.Printf("client frame cap too small: raise maxCQLFrameBody above %d", serverMaxFrameMB*1024*1024)
}

Try / catch

opcode, body, err := cqlRecv(conn)
if err != nil && strings.HasPrefix(err.Error(), "cassandra frame too large") {
    return fmt.Errorf("peer sent oversized frame; not a Cassandra node or cap too low: %w", err)
}

Prevention

When it happens

Trigger: Any caller of cqlRecv (doCassandraAuth, tryNoAuthConnection, identifyService) reads a header whose 4-byte body length field exceeds maxCQLFrameBody.

Common situations: Connecting to a non-Cassandra service that emits garbage interpreted as a huge length; stream desynchronization after a partial read; an extremely large server response exceeding the plugin's conservative cap.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/9efe5f9f7124294d. Report an issue: GitHub.