"The specified block list is invalid" while uploading blobs in parallel "The specified block list is invalid" while uploading blobs in parallel azure azure

"The specified block list is invalid" while uploading blobs in parallel


We ran into a similar issue, however we were not specifying any block ID or even using the block ID anywhere. In our case, we were using:

using (CloudBlobStream stream = blob.OpenWrite(condition)){   //// [write data to stream]   stream.Flush();   stream.Commit();}

This would cause The specified block list is invalid. errors under parallelized load. Switching this code to use the UploadFromStream(…) method while buffering the data into memory fixed the issue:

using (MemoryStream stream = new MemoryStream()){   //// [write data to stream]   stream.Seek(0, SeekOrigin.Begin);   blob.UploadFromStream(stream, condition);}

Obviously this could have negative memory ramifications if too much data is buffered into memory, but this is a simplification. One thing to note is that UploadFromStream(...) uses Commit() in some cases, but checks additional conditions to determine the best method to use.


This exception can happen also when multiple threads open stream into a blob with the same file name and try to write into this blob simultaneously.


NOTE: this solution is based on Azure JDK code, but I think we can safely assume that pure REST version will have the very same effect (as any other language actually).

Since I have spent entire work day fighting this issue, even if this is actually a corner case, I'll leave a note here, maybe it will be of help to someone.

I did everything right. I had block IDs in the right order, I had block IDs of the same length, I had a clean container with no leftovers of some previous blocks (these three reasons are the only ones I was able to find via Google).

There was one catch: I've been building my block list for commit via

CloudBlockBlob.commitBlockList(Iterable<BlockEntry> blockList)

with use of this constructor:

BlockEntry(String id, BlockSearchMode searchMode)

passing

BlockSearchMode.COMMITTED

in the second argument. And THAT proved to be the root cause. Once I changed it to

BlockSearchMode.UNCOMMITTED

and eventually landed on the one-parameter constructor

BlockEntry(String id)

which uses UNCOMMITED by default, commiting the block list worked and blob was successfuly persisted.