Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

ETag and Bytes discrepancy with a Put Block List replacing the same Block Blob

Aperta
#2,845 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
Mezza giornata
Idoneità per principianti
62/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
nodejs, typescript
Ambito
backend, databases

Direzione di ricerca

Start in LokiBlobMetadataStore.downloadBlob, which returns the live LokiJS record, and compare it with commitBlockList, which updates that record in place; BlobHandler reads blob.properties.etag after awaiting the body stream. The proposed fix is to return a copy of the record, and the test to add is tests/blob/unit/lokiBlobMetadataStore.unit.test.ts (@loki). Done when the downloaded model keeps v1's ETag, content length and block list after a v2 commit, and the test passes.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

When a ranged Get Blob runs while a Put Block List is replacing the same Block Blob, Azurite can return the new ETag together with the old bytes. Discovered when testing the operations against the container, used via a git patch file against the docker image for now but have a PR up to solve this issue also.

Details

downloadBlob returns the live LokiJS record, because LokiJS doesn't copy records on read. BlobHandler reads the block list, then waits on the body stream and the range MD5, and only then reads blob.properties.etag. During that wait, commitBlockList updates the same record in place. The response then pairs the old bytes, and an MD5 of those bytes, with the new ETag.

Clients can't detect this:

If-Match on later ranges passes, because the first range already returned the new ETag.
Each range's MD5 matches its own bytes, so content validation passes.
A chunked read returns a mix of two versions: old bytes in the first range and new bytes after.
On upstream 3.37.0, about half of the reads that ran alongside a commit came back mixed (264 of 540), with 0 MD5 mismatches. Real Azure serves each read from one version.

Proposed fix

Only affects the Loki metadata store.

Make LokiBlobMetadataStore.downloadBlob return a copy of the record instead of the live LokiJS record:

return structuredClone(doc); // was return doc;

commitBlockList makes all its changes with no await in between. So a copy taken by downloadBlob always holds one complete version, old or new. The ETag, block list and content length in a response then always belong to the same version.

The callers (block, page and append blob handlers, and copy) only read the returned model and never write it back, so a copy works for all of them. structuredClone needs Node 17 or later, and engines already requires Node 22 or later.

Test

A new unit test, tests/blob/unit/lokiBlobMetadataStore.unit.test.ts (@loki), uses an in-memory Loki store:

  1. Commit v1 of a Block Blob.
  2. Call downloadBlob.
  3. Commit v2.
  4. Check that the downloaded model still has v1's ETag, content length and block list, and that a new downloadBlob returns v2.

Without the fix the test fails with 'etag-v2' !== 'etag-v1'.

Lingua principale
TypeScript
Stelle
2.3k
Fork
399
Merge medio
1g 2h
PR unite (30g)
49

Preparare l'ambiente

  • Include un Dockerfile o un file Docker Compose
  • Ha un modello di pull request
  • Nessuna guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di Azure/Azurite

Tutte le issue di Azure/Azurite

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.