diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2QuarantineService.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2QuarantineService.java
index 1694d6db9409d53ecd4e0991c068a40bcb3ba956..7938fa52c7d6b5715e34dc65c1574b9dd290cbac 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2QuarantineService.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2QuarantineService.java
@@ -1,5 +1,7 @@
 package de.ozgcloud.nachrichten.postfach.osiv2.transfer;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.time.Duration;
 import java.util.Comparator;
 import java.util.List;
@@ -9,10 +11,12 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.function.BooleanSupplier;
+import java.util.stream.Stream;
 
 import de.ozgcloud.apilib.file.OzgCloudFile;
 import de.ozgcloud.nachrichten.postfach.osiv2.OsiPostfachException;
 import de.ozgcloud.nachrichten.postfach.osiv2.ServiceIfOsi2Enabled;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.FileChunkInfo;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2FileUpload;
 import de.ozgcloud.nachrichten.postfach.osiv2.storage.Osi2BinaryFileRemoteService;
 import lombok.RequiredArgsConstructor;
@@ -27,6 +31,7 @@ public class Osi2QuarantineService {
 
 	static final Duration POLLING_INTERVAL = Duration.ofSeconds(1);
 	static final Duration POLLING_TIMEOUT = Duration.ofMinutes(5);
+	static final int CHUNK_SIZE = 100 * (2 << 10);
 
 	public List<Osi2FileUpload> uploadAttachments(List<String> attachmentIds) {
 		var ozgCloudFiles = binaryFileService.getFileMetadataOfIds(attachmentIds);
@@ -44,14 +49,20 @@ public class Osi2QuarantineService {
 
 
 	Osi2FileUpload uploadFileToQuarantine(OzgCloudFile file) {
-//		binaryFileService.streamFileContent(file.getId().toString())
-//				.forEachRemaining(chunk -> postfachApiFacadeService.uploadChunk(file.getId(), chunk.getFileContent().toByteArray()));
+		try (var fileInputStream = binaryFileService.streamFileContent(file.getId().toString())) {
+			return uploadInputStreamToQuarantine(file, fileInputStream);
+		} catch (IOException e) {
+			throw new OsiPostfachException("Failed to upload file to quarantine!", e);
+		}
+	}
+
+	Osi2FileUpload uploadInputStreamToQuarantine(OzgCloudFile file, InputStream fileInputStream) {
+		// TODO
+		return null;
+	}
+
+	Stream<FileChunkInfo> streamFileChunkInfos(OzgCloudFile file) {
 		// TODO
-		//		var request = createRequestWithFileId(attachmentId);
-		//		var metadata = binaryFileService.findBinaryFilesMetaData(GrpcBinaryFilesRequest.newBuilder().)
-		//		var content = binaryFileService.getBinaryFileContent(request);
-		//
-		//		content.next().getFileContent().writeTo();
 		return null;
 	}
 
diff --git a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java
index e4d6b9b9802b41b45c8f1bdf26f48af22ae06479..bd43b7de6be09deaf45a1a7fbb9cdc6254293c3b 100644
--- a/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java
+++ b/src/main/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeService.java
@@ -5,13 +5,14 @@ import static de.ozgcloud.nachrichten.postfach.osiv2.transfer.Osi2RequestMapper.
 import java.util.List;
 import java.util.UUID;
 
+import org.springframework.core.io.AbstractResource;
+
 import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
 import de.ozgcloud.nachrichten.postfach.osiv2.ServiceIfOsi2Enabled;
 import de.ozgcloud.nachrichten.postfach.osiv2.config.Osi2PostfachProperties;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.MessageExchangeApi;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.QuarantineApi;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.FileChunkInfo;
-import de.ozgcloud.nachrichten.postfach.osiv2.model.FileChunkResource;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2FileUpload;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
@@ -34,14 +35,13 @@ public class PostfachApiFacadeService {
 		);
 	}
 
-	public void uploadChunk(FileChunkInfo chunkInfo, FileChunkResource chunkResource) {
-		// TODO
-		//		quarantineApi.uploadChunk(
-		//				requestMapper.mapDomainChunkMetaData(chunkInfo),
-		//				apiConfiguration.getTenant(),
-		//				apiConfiguration.getNameIdentifier(),
-		//				chunkResource
-		//		);
+	public <T extends AbstractResource> void uploadChunk(FileChunkInfo chunkInfo, T chunkResource) {
+			quarantineApi.uploadChunk(
+					requestMapper.mapDomainChunkMetaData(chunkInfo),
+					apiConfiguration.getTenant(),
+					apiConfiguration.getNameIdentifier(),
+					chunkResource
+			);
 	}
 
 	public List<String> fetchPendingMessageIds() {
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/FileChunkInfoTestFactory.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/FileChunkInfoTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f746028712cb62267f59af913d324654528fe9a
--- /dev/null
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/factory/FileChunkInfoTestFactory.java
@@ -0,0 +1,30 @@
+package de.ozgcloud.nachrichten.postfach.osiv2.factory;
+
+import java.util.UUID;
+
+import de.ozgcloud.nachrichten.postfach.osiv2.model.FileChunkInfo;
+
+public class FileChunkInfoTestFactory {
+
+	static final String FILE_UPLOAD_GUID = UUID.randomUUID().toString();
+	static final String FILE_NAME = "test-file-name";
+	static final String CONTENT_TYPE = "test-content-type";
+	static final Integer CHUNK_INDEX = 1;
+	static final Integer TOTAL_CHUNKS = 10;
+	static final Long TOTAL_FILE_SIZE = 1000L;
+
+
+	public static FileChunkInfo create() {
+		return createBuilder().build();
+	}
+
+	public static FileChunkInfo.FileChunkInfoBuilder createBuilder() {
+		return FileChunkInfo.builder()
+				.guid(FILE_UPLOAD_GUID)
+				.fileName(FILE_NAME)
+				.contentType(CONTENT_TYPE)
+				.chunkIndex(CHUNK_INDEX)
+				.totalChunks(TOTAL_CHUNKS)
+				.totalFileSize(TOTAL_FILE_SIZE);
+	}
+}
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2QuarantineServiceTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2QuarantineServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f0c34e89abd63e6a577c80d4ef30c774528f2df0
--- /dev/null
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/Osi2QuarantineServiceTest.java
@@ -0,0 +1,167 @@
+package de.ozgcloud.nachrichten.postfach.osiv2.transfer;
+
+import static de.ozgcloud.nachrichten.postfach.osiv2.transfer.Osi2FileUploadTestFactory.*;
+import static org.assertj.core.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.io.InputStream;
+import java.util.List;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+
+import de.ozgcloud.apilib.file.OzgCloudFile;
+import de.ozgcloud.apilib.file.OzgCloudFileId;
+import de.ozgcloud.apilib.file.OzgCloudFileTestFactory;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2FileUpload;
+import de.ozgcloud.nachrichten.postfach.osiv2.storage.Osi2BinaryFileRemoteService;
+import lombok.SneakyThrows;
+
+class Osi2QuarantineServiceTest {
+
+	@InjectMocks
+	@Spy
+	private Osi2QuarantineService service;
+
+	@Mock
+	private PostfachApiFacadeService postfachApiFacadeService;
+
+	@Mock
+	private Osi2BinaryFileRemoteService binaryFileService;
+
+	@DisplayName("upload attachments")
+	@Nested
+	class TestUploadAttachments {
+
+		private final OzgCloudFile file = OzgCloudFileTestFactory.create();
+		private final Osi2FileUpload uploadFile = Osi2FileUploadTestFactory.create();
+
+		@BeforeEach
+		void mock() {
+			when(binaryFileService.getFileMetadataOfIds(any())).thenReturn(List.of(file));
+			doReturn(List.of(uploadFile)).when(service).uploadFilesToQuarantineWithLargestFileFirst(any());
+			doNothing().when(service).waitForVirusScan(any());
+		}
+
+		@DisplayName("should call getFileMetadataOfIds")
+		@Test
+		void shouldCallGetFileMetadataOfIds() {
+			uploadAttachments();
+
+			verify(binaryFileService).getFileMetadataOfIds(List.of(UPLOAD_FILE_ID));
+		}
+
+		@DisplayName("should call uploadFilesToQuarantineWithLargestFileFirst")
+		@Test
+		void shouldCallUploadFilesToQuarantineWithLargestFileFirst() {
+			uploadAttachments();
+
+			verify(service).uploadFilesToQuarantineWithLargestFileFirst(List.of(file));
+		}
+
+		@DisplayName("should call waitForVirusScan")
+		@Test
+		void shouldCallWaitForVirusScan() {
+			uploadAttachments();
+
+			verify(service).waitForVirusScan(List.of(uploadFile));
+		}
+
+		@DisplayName("should return")
+		@Test
+		void shouldReturn() {
+			var result = uploadAttachments();
+
+			assertThat(result).containsExactly(uploadFile);
+		}
+
+		List<Osi2FileUpload> uploadAttachments() {
+			return service.uploadAttachments(List.of(UPLOAD_FILE_ID));
+		}
+	}
+
+	@DisplayName("upload files to quarantine with largest file first")
+	@Nested
+	class TestUploadFilesToQuarantineWithLargestFileFirst {
+
+		private final OzgCloudFile file1 = OzgCloudFileTestFactory.createBuilder()
+				.id(new OzgCloudFileId(UPLOAD_FILE_ID))
+				.size(1000L)
+				.build();
+		private final OzgCloudFile file2 = OzgCloudFileTestFactory.createBuilder()
+				.size(2000L)
+				.build();
+		private final Osi2FileUpload uploadFile1 = Osi2FileUploadTestFactory.createBuilder().file(file1).build();
+		private final Osi2FileUpload uploadFile2 = Osi2FileUploadTestFactory.createBuilder().file(file2).build();
+
+		@BeforeEach
+		void mock() {
+			doReturn(uploadFile1).when(service).uploadFileToQuarantine(file1);
+			doReturn(uploadFile2).when(service).uploadFileToQuarantine(file2);
+		}
+
+		@DisplayName("should return")
+		@Test
+		void shouldReturn() {
+			var result = uploadFilesToQuarantineWithLargestFileFirst();
+
+			assertThat(result).containsExactly(uploadFile2, uploadFile1);
+		}
+
+		List<Osi2FileUpload> uploadFilesToQuarantineWithLargestFileFirst() {
+			return service.uploadFilesToQuarantineWithLargestFileFirst(List.of(file1, file2));
+		}
+	}
+
+	@DisplayName("upload file to quarantine")
+	@Nested
+	class TestUploadFileToQuarantine {
+
+		@Mock
+		private InputStream fileInputStream;
+
+		private final OzgCloudFile file = OzgCloudFileTestFactory.create();
+		private final Osi2FileUpload uploadFile = Osi2FileUploadTestFactory.create();
+
+		@BeforeEach
+		void mock() {
+			when(binaryFileService.streamFileContent(any())).thenReturn(fileInputStream);
+			doReturn(uploadFile).when(service).uploadInputStreamToQuarantine(any(), any());
+		}
+
+		@DisplayName("should call streamFileContent")
+		@Test
+		void shouldCallStreamFileContent() {
+			uploadFileToQuarantine();
+
+			verify(binaryFileService).streamFileContent(OzgCloudFileTestFactory.ID_STR);
+		}
+
+		@DisplayName("should call uploadInputStreamToQuarantine")
+		@Test
+		void shouldCallUploadInputStreamToQuarantine() {
+			uploadFileToQuarantine();
+
+			verify(service).uploadInputStreamToQuarantine(file, fileInputStream);
+		}
+
+		@DisplayName("should return")
+		@Test
+		void shouldReturn() {
+			var result = uploadFileToQuarantine();
+
+			assertThat(result).isEqualTo(uploadFile);
+		}
+
+		Osi2FileUpload uploadFileToQuarantine() {
+			return service.uploadFileToQuarantine(file);
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeServiceTest.java b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeServiceTest.java
index faf012b0373acb1ea8d98e359de78379df7b8852..0f9b57d824813196948f83a8117147c43ebd81aa 100644
--- a/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeServiceTest.java
+++ b/src/test/java/de/ozgcloud/nachrichten/postfach/osiv2/transfer/PostfachApiFacadeServiceTest.java
@@ -18,14 +18,20 @@ import org.mockito.Mock;
 import org.mockito.Spy;
 
 import de.ozgcloud.nachrichten.postfach.PostfachNachricht;
+import de.ozgcloud.nachrichten.postfach.osiv2.config.Osi2PostfachProperties;
+import de.ozgcloud.nachrichten.postfach.osiv2.factory.FileChunkInfoTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.MessageExchangeReceiveMessagesResponseTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.factory.PostfachNachrichtTestFactory;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.MessageExchangeApi;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.api.QuarantineApi;
+import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.DomainChunkMetaData;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeDeleteMessageResponse;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeReceiveMessagesResponse;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.MessageExchangeSendMessageResponse;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.OutSendMessageRequestV2;
 import de.ozgcloud.nachrichten.postfach.osiv2.gen.model.V1ReplyMessage;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.FileChunkInfo;
+import de.ozgcloud.nachrichten.postfach.osiv2.model.FileChunkResource;
 import de.ozgcloud.nachrichten.postfach.osiv2.model.Osi2FileUpload;
 
 class PostfachApiFacadeServiceTest {
@@ -37,12 +43,18 @@ class PostfachApiFacadeServiceTest {
 	@Mock
 	MessageExchangeApi messageExchangeApi;
 
+	@Mock
+	QuarantineApi quarantineApi;
+
 	@Mock
 	Osi2RequestMapper osi2RequestMapper;
 
 	@Mock
 	Osi2ResponseMapper osi2ResponseMapper;
 
+	@Mock
+	Osi2PostfachProperties.ApiConfiguration apiConfiguration;
+
 	@DisplayName("send message")
 	@Nested
 	class TestSendMessage {
@@ -179,6 +191,44 @@ class PostfachApiFacadeServiceTest {
 		}
 	}
 
+	@DisplayName("upload chunk")
+	@Nested
+	class TestUploadChunk {
+		@Mock
+		FileChunkResource chunkResource;
+
+		@Mock
+		DomainChunkMetaData domainChunkMetaData;
+
+		private static final String TENANT = "tenant";
+		private static final String NAME_IDENTIFIER = "nameIdentifier";
+
+		private final FileChunkInfo info = FileChunkInfoTestFactory.create();
+
+		@BeforeEach
+		void mock() {
+			when(apiConfiguration.getTenant()).thenReturn(TENANT);
+			when(apiConfiguration.getNameIdentifier()).thenReturn(NAME_IDENTIFIER);
+			when(osi2RequestMapper.mapDomainChunkMetaData(any())).thenReturn(domainChunkMetaData);
+		}
+
+		@DisplayName("should call mapDomainChunkMetadata")
+		@Test
+		void shouldCallMapDomainChunkMetadata() {
+			postfachApiFacadeService.uploadChunk(info, chunkResource);
+
+			verify(osi2RequestMapper).mapDomainChunkMetaData(info);
+		}
+
+		@DisplayName("should call uploadChunk")
+		@Test
+		void shouldCallUploadChunk() {
+			postfachApiFacadeService.uploadChunk(info, chunkResource);
+
+			verify(quarantineApi).uploadChunk(domainChunkMetaData, TENANT, NAME_IDENTIFIER, chunkResource);
+		}
+	}
+
 	@DisplayName("Delete Message")
 	@Nested
 	class TestDeleteMessage {