Skip to content

Hash acquires a duplicate field → replica full-sync fails in a loop ("Duplicate hash fields detected") and primary stalls ("Stalled heartbeat() fiber") — v1.34.2 #8424

Open

Description

@rafi-par

Describe the bug

A hash written only via HSET intermittently ends up containing a duplicate field. When the replica performs a full sync, the RDB loader rejects that hash and the sync fails and retries in a loop. During the loop the primary becomes unresponsive (Stalled heartbeat() fiber for an extended period), so clients get connection timeouts until the affected key expires on its own.

This is a Dragonfly→Dragonfly setup (no RESTORE, no external RDB import). The client uses plain HSET only, so the duplicate field appears to be created internally by the server.

Symptoms / logs (key name redacted)

On the replica during full sync:

rdb_load.cc:525] Duplicate hash fields detected for field ...
rdb_load.cc:2604] Could not load value for key '<hash-key>' in DB 0
common.cc:341] ReportError: Internal error when loading RDB file N: Error loading rdb format
replica.cc:268] Error syncing with <master>:<port> (phase: INITIAL_SYNC): dragonfly.rdbload:N Internal error when loading RDB file N

On the primary (concurrently, escalating):

engine_shard.cc:618] Stalled heartbeat() fiber for <N> seconds   # observed climbing to ~1400s

The replica repeatedly re-attempts full sync (Started full sync → error → retry). The incident cleared only when the affected hash key expired via its TTL.

Workload characteristics

  • Data structure: a single hash per rotating time-bucket key.
  • Writes: HSET only (multiple field/value pairs per call).
  • Field names are fixed-length binary (byte arrays that can contain null bytes).
  • Key-level TTL is (re)applied on writes (EXPIRE, "always" semantics).
  • No field-level TTL (HEXPIRE/HGETEX/HSETEX) and no RESTORE are used.

What we ruled out

  • Not client misuse — HSET overwrites existing fields, so the application cannot create duplicate fields.
  • Not field-level TTL / lazy field expiry.
  • Not a RESTORE or foreign-RDB import path (this is native Dragonfly replication).

Expected behavior

  1. A hash should never hold duplicate fields when written via HSET (binary field names should compare correctly).
  2. A single corrupt key should not put full sync into an infinite retry loop or stall the primary — it should be surfaced/skipped so replication can make progress and the primary stays responsive.

To reproduce

Not deterministically reproducible — appears intermittent under sustained HSET load to hashes with binary field names. Steps we believe are relevant:

  1. 1 primary + 1 replica.
  2. Continuously HSET many entries into a hash using fixed-length binary field names; apply a key-level TTL.
  3. Trigger/allow a replica full sync while under load.
  4. Observe (occasionally) the replica full-sync failing on Duplicate hash fields detected and the primary's Stalled heartbeat() fiber.

Environment

  • Dragonfly v1.34.2
  • Kubernetes (dragonfly-operator), 1 primary + 1 replica

Questions

Activity

  1. vyavdoshenko commented on Sep 30, 2026

    @vyavdoshenko
    Contributor

    @rafi-par
    Thanks for reporting the issue. I suggest trying the latest version. We fixed a bunch of related issues.
    Please let us know if it's reproducible in version v2.0.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions