# Protobuf deserialization silently converts unknown enum values to 0 causing logic errors

- **ID:** `data/protobuf-enum-value-out-of-range`
- **Domain:** data
- **Category:** data_error
- **Verification:** ai_generated
- **Fix Rate:** 85%

## Root Cause

Protobuf specification mandates that unknown enum values are preserved in the wire format but deserialized as 0 (the default enum value), leading to silent data corruption when the enum is used in business logic.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| Protobuf 3.21.0+ | active | — | — |
| gRPC 1.50.0+ | active | — | — |
| Java Protobuf 3.21.0+ | active | — | — |
| Python protobuf 4.21.0+ | active | — | — |

## Workarounds

1. **Use `google.protobuf.EnumValueDescriptor` to check if the value is known: `if not enum_descriptor.values_by_number.get(raw_value): raise ValueError('Unknown enum')`** (90% success)
   ```
   Use `google.protobuf.EnumValueDescriptor` to check if the value is known: `if not enum_descriptor.values_by_number.get(raw_value): raise ValueError('Unknown enum')`
   ```
2. **Store the raw integer value in a separate field alongside the enum: `message Event { Status status = 1; int32 raw_status = 2; }`** (85% success)
   ```
   Store the raw integer value in a separate field alongside the enum: `message Event { Status status = 1; int32 raw_status = 2; }`
   ```
3. **Use a custom deserialization function that validates enum values against a known set before conversion.** (80% success)
   ```
   Use a custom deserialization function that validates enum values against a known set before conversion.
   ```

## Dead Ends

- **** — Protobuf treats 0 as the default even if named; unknown values still become 0, and logic cannot distinguish between 'intentional 0' and 'unknown'. (70% fail)
- **** — `allow_alias` is for multiple names mapping to same number, not for handling unknown values. (90% fail)
