Java: openjdk version "1.8.0_163" OpenJDK Runtime Environment (Zulu 8.28.0.1-linux64) (build 1.8.0_163-b01) OpenJDK 64-Bit Server VM (Zulu 8.28.0.1-linux64) (build 25.163-b01, mixed mode)
OS: Ubuntu 18.04 Linux local 4.15.0-23-generic #25-Ubuntu SMP Wed May 23 18:02:16 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux The problem is that org.apache.tomcat.util.http.fileupload.MultipartStream.ItemInputStream#read(byte[], int, int) method does not update pos field after reading from buffer / stream. Unfortunately I cannot provide full example as this is private project. Here are sample unit tests. First reproduces the error and second use reflection to set proper field value to simulate proper behaviour: package org.apache.tomcat.util.http.fileupload; import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; import java.io.IOException; import java.lang.reflect.Field; import static org.assertj.core.api.Assertions.assertThat; class ItemInputStreamTest { @Test void Should_Read_Bytes_But_Throws_Exception() throws IOException { // given byte[] bytes = new byte[]{1, 2, 3}; final ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); final MultipartStream.ProgressNotifier progressNotifier = new MultipartStream.ProgressNotifier(null, 1111); final MultipartStream multipartStream = new MultipartStream(inputStream, bytes, progressNotifier); MultipartStream.ItemInputStream itemInputStream = multipartStream.new ItemInputStream(); // when byte[] buffer = new byte[8196]; int result = itemInputStream.read(buffer, 0, 8196); // then assertThat(result).isEqualTo(3); } @Test void Should_Read_Bytes_Fixed() throws IOException, NoSuchFieldException, IllegalAccessException { // given byte[] bytes = new byte[]{1, 2, 3}; final ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); final MultipartStream.ProgressNotifier progressNotifier = new MultipartStream.ProgressNotifier(null, 1111); final MultipartStream multipartStream = new MultipartStream(inputStream, bytes, progressNotifier); MultipartStream.ItemInputStream itemInputStream = multipartStream.new ItemInputStream(); Field pos = itemInputStream.getClass() .getDeclaredField("pos"); pos.setAccessible(true); pos.set(itemInputStream, 3); // when byte[] buffer = new byte[8196]; int result = itemInputStream.read(buffer, 0, 8196); // then assertThat(result).isEqualTo(3); } }