So the root cause is that fsck -move will throw exception for all good blocks. A sample exception is pasted in the description. We can see the problematic method is RemoteBlockReader2#readTrailingEmptyPacket. Thanks Shengjun for reporting this jira with good details.
The reason is that fsck sets the length to -1, but seems the RemoteBlockReader2 code doesn't support that, and will consider the read finished after the first iteration. Of course there are usually more than 1 buffer size of data to be read, so the above exception is seen.
I think a quick fix to this would be to pass in the length when creating the block reader, like all other places of invocation do. Patch 1 implements this idea, and polished John's test case.