Bug: Kafka ProtobufDeserializer reads Confluent message indexes as plain varints, dropping fields or failing for non-first message types
メンテナーはふだん 1 日以内に返信
評価
この issue はまだ評価されていません。
説明
Expected Behaviour
A Protobuf value produced with Confluent Schema Registry decodes into every field, whatever message index the serializer wrote. Confluent's serializers write the message index array as zigzag encoded varints (array length, then each index), with [0] as a single 0x00 byte; see _encode_varints / _read_index_array in confluent_kafka.schema_registry.protobuf.
Current Behaviour
ProtobufDeserializer._remove_message_index (kafka/deserializer/protobuf.py) reads the array with _DecodeSignedVarint, so it reads twice the real length. Only index [0] works. For any other index:
- it skips payload bytes as if they were indexes, and the record either fails with
DecodeError: Wire format was corrupt, or - it decodes without error but with fields silently missing.
The second case is already in the repo's fixture: record offset 17 in tests/functional/kafka_consumer/_protobuf/schemas/complex_schema_with_confuent.py has the prefix 04 02 00 (zigzag for [1, 0]) and decodes without userId and name. test_confluent_schema_registry_complex_schema only asserts email and age, so it passes.
Code snippet
import base64
from google.protobuf.descriptor_pb2 import FieldDescriptorProto
from aws_lambda_powertools.utilities.kafka import ConsumerRecords, SchemaConfig, kafka_consumer
def confluent_framed(message, indexes):
# Message index array as confluent_kafka's ProtobufSerializer writes it: zigzag varints, [0] as a single 0x00
def zigzag(v):
v, out = (v << 1) ^ (v >> 63), bytearray()
while v & ~0x7F:
out.append((v & 0x7F) | 0x80)
v >>= 7
return bytes(out + bytes([v]))
prefix = b"\x00" if indexes == [0] else zigzag(len(indexes)) + b"".join(zigzag(i) for i in indexes)
return base64.b64encode(prefix + message.SerializeToString()).decode()
message = FieldDescriptorProto(name="order_id", number=1, json_name="orderId")
@kafka_consumer(schema_config=SchemaConfig(value_schema_type="PROTOBUF", value_schema=FieldDescriptorProto))
def handler(event: ConsumerRecords, context):
return next(event.records).value
for indexes in ([0], [1, 0], [2]):
event = {
"eventSource": "aws:kafka",
"records": {
"orders-0": [
{
"topic": "orders", "partition": 0, "offset": 1, "timestamp": 1, "timestampType": "CREATE_TIME",
"key": None, "headers": [],
"value": confluent_framed(message, indexes),
"valueSchemaMetadata": {"schemaId": "1", "dataFormat": "PROTOBUF"},
},
],
},
}
try:
print(f"message index {indexes}: {handler(event, None)}")
except Exception as exc:
print(f"message index {indexes}: {type(exc).__name__}: {exc}")
Possible Solution
Decode the array as zigzag varints: read the length with _DecodeVarint and apply (n >> 1) ^ -(n & 1), then skip that many zigzag varints. Also assert userId and name in test_confluent_schema_registry_complex_schema, and add a parametrised test for indexes [0], [1], [2], [1, 0] and a multi-byte index. I have this ready with tests (all Kafka tests pass) and am happy to open the PR.
Trade-off to flag: producers still on Confluent's deprecated format (use.deprecated.format=True, plain varints) decode correctly today, and after this change only index [0] would keep working for them. Confluent's client warns that format is slated for removal and its default is zigzag, so I'd fix the default. If you want to keep the deprecated format supported, an opt-in flag on SchemaConfig could select it. Happy to add that.
Steps to Reproduce
Run the snippet above. No Kafka or AWS access needed.
Powertools for AWS Lambda (Python) version
latest (develop @ 5785377)
AWS Lambda function runtime
3.13
Packaging format used
PyPi
Debugging logs
Output of the snippet on develop:
message index [0]: {'name': 'order_id', 'number': 1, 'json_name': 'orderId'}
message index [1, 0]: KafkaConsumerDeserializationError: Error trying to deserialize protobuf data - DecodeError: Error parsing message with type 'google.protobuf.FieldDescriptorProto': Wire format was corrupt
message index [2]: KafkaConsumerDeserializationError: Error trying to deserialize protobuf data - DecodeError: Error parsing message with type 'google.protobuf.FieldDescriptorProto': Wire format was corrupt
- 主要言語
- Python
- スター
- 3.3k
- フォーク
- 511
- 平均マージ
- 3日 8時間
- マージ済み PR(30日)
- 92
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
aws-powertools/powertools-lambda-python のほかの issue
-
Bug: POWERTOOLS_IDEMPOTENCY_DISABLED set to an empty or non-boolean value crashes every invocation対応中かも @lechakrawarthy が 1 日前に担当しました。 オープンbug good first issue help wanted idempotency
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
aws-powertools/powertools-lambda-python#8728 · コメント 4 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
Bug: Redis layer fails the invocation instead of retrying when a record expires between SET NX and GET対応中かも @coughlmao が 1 日前に担当しました。 オープンbug good first issue help wanted idempotency
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
aws-powertools/powertools-lambda-python#8727 · コメント 4 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
Bug: Redis orphan lock timeout ignores expires_after_seconds and is always 10 seconds対応中かも @CJstate が 1 日前に担当しました。 オープンbug good first issue help wanted idempotency
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
aws-powertools/powertools-lambda-python#8726 · コメント 3 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
Bug: idempotency payloads with set, frozenset or bytes fields cannot be hashed対応中かも @Neeraj111010 が 1 日前に担当しました。 オープンbug good first issue help wanted idempotency
難易度 2/5 1〜3時間 初心者へのやさしさ 80/100
aws-powertools/powertools-lambda-python#8725 · コメント 6 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
Bug: with a DynamoDB composite key, DataRecord.idempotency_key is the static partition key value対応中かも @sumedh-aerram が 1 日前に担当しました。 オープンbug good first issue help wanted idempotency
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
aws-powertools/powertools-lambda-python#8724 · コメント 3 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
aws-powertools/powertools-lambda-python の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
earthtojake/text-to-cad#758 ·
メンテナーはふだん 1 日以内に返信
-
domain:upgrades enhancement needs-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
gke-labs/kube-agents#4634 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
agardnerIT/opamp-server-py#116 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
enhancement good first issue
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
elviskahoro/sdk-python-attio#144 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信