flagd: fractional operator uses wrong bucketing formula — unsigned u32::MAX divisor instead of signed i32::MAX
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 75/100
Research direction
Start in the Rust in-process provider at fractional.rs lines 78-79 and inspect the existing fractional-operator test coverage. Verify the bucket calculation against the signed i32::MAX-based formula described in the issue, then run the relevant test suite; done means the Rust provider produces cross-SDK-consistent assignments.
Written by the indexing model from the issue text.
Description
Summary
The fractional operator's MurmurHash bucketing formula in the Rust in-process provider uses an unsigned division that produces different bucket assignments from every other SDK. Users running the same flag configuration across multiple SDKs will get inconsistent variant assignments for the same targeting key.
Current Behavior
fractional.rs:78-79:
let hash: u32 = murmurhash3_x86_32(bucket_by.as_bytes(), 0);
let bucket = (hash as f64 / u32::MAX as f64) * 100.0;
This divides the raw unsigned 32-bit hash by u32::MAX (4,294,967,295), producing a bucket in [0, 100].
Expected Behavior
All other SDKs cast to signed i32, take the absolute value, and divide by i32::MAX (2,147,483,647):
Go:
hashValue := int32(murmur3.StringSum32(value))
hashRatio := math.Abs(float64(hashValue)) / math.MaxInt32
bucket := hashRatio * 100
Java:
int mmrHash = MurmurHash3.hash32x86(bytes, 0, bytes.length, 0);
float bucket = Math.abs(mmrHash) * 1.0f / Integer.MAX_VALUE * 100;
Python:
hash_ratio = abs(mmh3.hash(bucket_by)) / (2**31 - 1)
bucket = hash_ratio * 100
The Rust implementation should be:
let hash: u32 = murmurhash3_x86_32(bucket_by.as_bytes(), 0);
let signed = hash as i32;
let bucket = (signed as f64).abs() / (i32::MAX as f64) * 100.0;
Impact
For any given (flagKey, targetingKey) pair, the Rust provider will assign a different bucket value than Go/Java/JS/Python/.NET. This means users migrating between SDKs or running multiple SDKs against the same flag configuration will see different variant assignments.
Related
- open-feature/flagd#1872 — Cross-SDK
fractionaloperator bucketing inconsistencies - #84 — Harden hashing consistency (ADR for future CBOR-based approach, separate from this bug)
- Dominant language
- Rust
- Stars
- 15
- Forks
- 18
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 1
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from open-feature/rust-sdk-contrib
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
open-feature/rust-sdk-contrib#151 ·
-
Difficulty 4/5 3-5 days Newbie friendliness 42/100
open-feature/rust-sdk-contrib#124 · 4 comments · 1 reaction ·
-
Difficulty 4/5 3-5 days Newbie friendliness 45/100
open-feature/rust-sdk-contrib#116 ·
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
open-feature/rust-sdk-contrib#103 · 1 comment ·
-
enhancement
Difficulty 3/5 1-2 days Newbie friendliness 52/100
open-feature/rust-sdk-contrib#101 · 3 comments · 1 reaction ·
All issues in open-feature/rust-sdk-contrib
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
gitbutlerapp/gitbutler#15998 · 1 comment ·
-
bug triage:deciding
Difficulty 1/5 Under an hour Newbie friendliness 88/100
open-telemetry/otel-arrow#4132 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100