- 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.