Skip to content

Join failures in mixed-client environments due to ratchet tree consistency drift #57

Description

@gzuuus

In dogfooding with mixed Marmot implementations, invitees sometimes receive and decrypt welcome events but fail to join the group.

Observed error (surfaced by joinGroupFromWelcome()):

Failed to join group with any matching key package. Last error: non-blank intermediate node must list leaf node in its unmerged_leaves

This points to strict ratchet-tree validation failure in ts-mls (see validateRatchetTree(), specifically the unmerged_leaves invariant around arraysEqual(...)).


Context

  • Environment had multiple users/admins and mixed implementations.
  • Some clients were known to do aggressive self-update behavior.
  • Symptoms are consistent with state fork/drift around invite/join windows rather than transport/inbox failure.

Why this matters

A single divergent implementation can destabilize onboarding for new members by producing/propagating welcomes tied to inconsistent tree state. This creates poor interoperability and difficult-to-debug failures.


Analysis branch + doc


Likely root causes (ranked)

  1. Ratchet tree consistency drift in mixed implementations (most likely).
  2. Stale/divergent commit producer state under concurrent admin activity.

Contributors include:

  • aggressive self-updates near join/invite timing
  • concurrent membership-changing commits
  • delayed/out-of-order ingestion
  • implementation differences in sequencing/proposal handling

Proposed actions (future iteration)

  1. Add structured typed join errors (e.g. WELCOME_TREE_INCONSISTENT) in joinGroupFromWelcome().
  2. Add targeted join diagnostics (candidate refs, per-attempt inner errors, welcome/tree metadata).
  3. Add optional interop-safe commit mode in MarmotGroup.commit() to serialize risky transitions.
  4. Add drift/fork preflight checks before creating new commits.
  5. Add welcome quality gates before send path around createWelcomeRumor().
  6. Add quarantine policy for repeatedly incompatible client fingerprints.
  7. Expand race/interop tests near ingest-commit-race.test.ts and end-to-end-invite-join-message.test.ts.

Non-goal

Do not weaken MLS validation to accept inconsistent tree states. The fix direction is stronger diagnostics, safer sequencing, and better interop guardrails.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions