Turns out archive/zip doesn't like a ReadAt that returns n>0 AND io.EOF (even if the specification for ReaderAt/Read say this should be possible).