A failed upload must not become a dedup match

Fixkamo-shared-library
Ya
27 Agosti 2026, 05:24 UTC
Mwandishi
Kamo
Ahadi ya
f848f39

A member sent an 11 MB .wav to a chat, got "Cannot invoke ObjectWriteResponse.etag() because response is null", sent it again, and the second one delivered instantly — pointing at bytes that were never stored. Every attempt to play it 500'd with "Object does not exist". Two defects in series. minio-java 8.5.7 has a third outcome for putObject that is neither a result nor an exception: when a MULTIPART upload fails and the compensating abort then SUCCEEDS, S3Base.putMultipartObjectAsync falls out of its catch block and returns the still-null response instead of rethrowing (bytecode offsets 147→171→226→228). Reading its etag threw a NullPointerException, which is not in the per-node catch list — so it escaped the failover loop and the remaining MinIO nodes were never tried. Treat a null write result as a failed node instead: the loop moves on, and if every node fails the caller is told the object was not stored. The row survived it. storeContentAddressed writes the ImgDat with isMissing=true BEFORE the bytes go to storage, which is deliberate — a crash must leave a row that admits it holds nothing. But no dedup lookup checked that flag, so the dead row was a perfectly good match, and the streaming path is not @Transactional so nothing rolled it back. Every dedup query now matches published content only, and a caught upload failure discards the row it just wrote. Only multipart uploads can fail this way, so it was invisible for small files and waited for exactly the large ones a member most minds losing.

Mabadiliko yote

Je, unaona nini kuhusu usafiri?

Kila moja ya hizi updates ardhi katika nafasi yako ya kazi moja kwa moja. Kuanza bure na kuangalia kukua wiki baada ya wiki.

Kuwa Huru MileleMtazamo wa bei