influxdata/influxdb · warning

sharder mapped input to non-existant bucket

Error message

sharder mapped input to non-existant bucket

What it means

JumpHash implements Google's jump consistent hash: the loop advances bucket b while j < shards.len(), so on exit b must be a valid index. The .expect('sharder mapped input to non-existant bucket') is a defensive invariant guard after assert!(b >= 0) — by construction of the loop it should be unreachable, because b always holds a j that was < shards.len(). Seeing it means the jump-hash arithmetic produced an out-of-range bucket (e.g. an f64-to-i64 cast edge in the j computation) or the shards vector was mutated/aliased after construction.

Source

Thrown at core/sharder/src/jumphash.rs:104

        H: Hash,
    {
        let mut state = self.hasher;
        key.hash(&mut state);
        let mut key = state.finish();

        let mut b = -1;
        let mut j = 0;
        while j < self.shards.len() as i64 {
            b = j;
            key = key.wrapping_mul(2862933555777941757).wrapping_add(1);
            j = ((b.wrapping_add(1) as f64) * (((1u64 << 31) as f64) / (((key >> 33) + 1) as f64)))
                as i64
        }

        assert!(b >= 0);
        self.shards
            .get(b as usize)
            .expect("sharder mapped input to non-existant bucket")
    }

    /// Consistently hash a table and namespace to a `T`. For use in a situation where you don't
    /// have a payload.
    pub fn shard_for_query(&self, table: &str, namespace: &str) -> &T {
        // The derived hash impl for HashKey is hardened against prefix
        // collisions when combining the two fields.
        self.hash(&HashKey { table, namespace })
    }
}

#[derive(Hash)]
struct HashKey<'a> {
    table: &'a str,
    namespace: &'a str,
}

/// A [`JumpHash`] sharder mapping a [`MutableBatch`] reference according to the

View on GitHub (pinned to d28e26e048)

Solutions

  1. Treat it as a bug: capture the key, shards.len(), and crate versions and file an issue against the sharder crate — do not try to 'fix' it in calling code.
  2. Verify the JumpHash instance is not constructed once and then have its shard list changed underneath (immutability guarantees shards order); rebuild the sharder when topology changes.
  3. Ensure the constructor path ran (the 'empty shard set given to sharder' assert) so an empty shard set fails fast at startup instead of at first hash.
  4. Pin dependency versions (siphasher) so hash/cast behavior matches the tested build; the repo keeps test_key_bucket_fixture for exactly this mapping stability.

Example fix

// No caller-side fix: b is guaranteed < shards.len() by the loop.
// If hit, add a reproducing test:

#[test]
fn repro_out_of_bounds_bucket() {
    let hasher = JumpHash::new((0..1_000).map(Arc::new));
    for k in 0..1_000_000u64 {
        let _ = hasher.hash(k); // panics here => jump-hash math bug, report upstream
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// The constructor already asserts non-empty; validate before building:
let shards: Vec<_> = nodes.collect();
if shards.is_empty() {
    return Err("refusing to start with zero shards");
}
let sharder = JumpHash::new(shards);

Type guard

fn has_shards<T>(v: &[T]) -> bool { !v.is_empty() }

Prevention

When it happens

Trigger: Calling JumpHash::hash / shard / shard_for_query on a sharder whose internal state no longer matches what the loop assumed. The constructor already asserts a non-empty shard set, so an empty shard list panics earlier ('empty shard set given to sharder'), not here. In practice this expect has no normal trigger; it fires only on an implementation bug or memory corruption of the shards Vec.

Common situations: Almost never seen; if reported, it follows a dependency upgrade that changed integer/float casting behavior in the jump-hash loop, a fork that altered the shard list after construction, or a corrupted Vec. InfluxDB Enterprise router/sharding code paths (sharding data by table+namespace across nodes) would be the place it surfaces.

Related errors


AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16). Data as JSON: /api/errors/93957a5ffed762d5. Report an issue: GitHub.