Skip to content

Claim-check [Blob] properties are off-loaded but not re-hydrated on a local queue #3047

Closed

Description

@prom3theu5

Summary

When a [Blob]-marked message is delivered via an in-process (durable) local queue, the claim-check serializer's Write off-loads the payload and nulls the property on the in-memory message (ClaimCheckMessageSerializer → accessor.Clear(message)), but the receive path reuses that same object and skips deserialization (HandlerPipeline: if (envelope.Message == null) is false), so ReadFromData/LoadBlobsAsync never re-hydrate. The handler receives a null payload.

It works correctly across a real transport (Rabbit/TCP/etc.) because that path forces a serialize→deserialize round-trip. Local delivery does not.

Mechanism

  1. A durable local queue serializes the envelope on store (DurableLocalQueue.writeMessageData → Serializer.Write(envelope)), which fires the claim-check off-load + Clear(message) against the live in-memory message.
  2. The durable queue then re-enqueues that same Envelope instance to its receiver.
  3. In HandlerPipeline.executeAsync, envelope.Message is not null (it's the cleared object), so the deserialize branch — the only place LoadBlobsAsync re-hydrates — never runs.

A buffered (in-memory) local queue does not reproduce this: it never serializes on the local hand-off, so the off-load never fires. InvokeMessageAndWaitAsync also doesn't reproduce it (the handler runs inline, bypassing store-and-forward).

Expected

Local delivery should either not off-load, or off-load and re-hydrate symmetrically — the handler should always see the original payload.

Repro

Single host, UseClaimCheck(c => c.UseFileSystem(...)), Policies.UseDurableLocalQueues(), a local handler for a [Blob] message, SendMessageAndWaitAsync — the handler's blob property comes back null instead of the sent value.

Note

EncryptingMessageSerializer (the sibling serializer-decorator) does not mutate the in-memory message and is unaffected; claim-check's in-place Clear(message) is the root of the asymmetry. A fix should keep the serializer from leaving the live message mutated, matching the encryption precedent.

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