diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts
index 19cd002222b625f513309a5bf98a72aa9a982e7f..a120af6e0825c4a292affa1f14694eb0c3184411 100644
--- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts
+++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.spec.ts
@@ -927,6 +927,14 @@ describe('BescheidService', () => {
         singleCold(createEmptyStateResource()),
       );
     });
+
+    it('should emit empty state resource uploaded attachment', () => {
+      service.init();
+
+      expect(service.getUploadedAttachment()).toBeObservable(
+        singleCold(createEmptyStateResource()),
+      );
+    });
   });
 
   describe('create bescheid document', () => {
@@ -1351,4 +1359,98 @@ describe('BescheidService', () => {
       expect(service.bescheidListService.refresh).toHaveBeenCalled();
     });
   });
+
+  describe('uploadAttachment', () => {
+    const bescheidResource: BescheidResource = createBescheidResource([
+      BescheidLinkRel.UPLOAD_ATTACHMENT,
+    ]);
+    const file: File = createFile();
+    const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(
+      createBinaryFileResource(),
+    );
+
+    beforeEach(() => {
+      binaryFileService.uploadFile.mockReturnValue(of(binaryFileStateResource));
+      service.handleAttachmentUpload = jest.fn();
+    });
+
+    it('should emit upload in progress', () => {
+      service.uploadAttachment(bescheidResource, file).subscribe();
+
+      expect(service.getUploadAttachmentInProgress()).toBeObservable(
+        singleCold({ fileName: file.name, loading: true } as UploadFileInProgress),
+      );
+    });
+
+    it('should upload file', (done) => {
+      service.uploadAttachment(bescheidResource, file).subscribe(() => {
+        expect(binaryFileService.uploadFile).toBeCalledWith(
+          bescheidResource,
+          BescheidLinkRel.UPLOAD_ATTACHMENT,
+          file,
+          false,
+        );
+        done();
+      });
+    });
+
+    it('should handle attachment upload', (done) => {
+      service.uploadAttachment(bescheidResource, file).subscribe(() => {
+        expect(service.handleAttachmentUpload).toBeCalledWith(binaryFileStateResource);
+        done();
+      });
+    });
+
+    it('should emit uploaded binary file', () => {
+      expect(service.uploadAttachment(bescheidResource, file)).toBeObservable(
+        singleColdCompleted(binaryFileStateResource),
+      );
+    });
+  });
+
+  describe('handleAttachmentUpload', () => {
+    describe('on error', () => {
+      const binaryFileStateResource: StateResource<BinaryFileResource> =
+        createErrorStateResource(createApiError());
+
+      it('should emit upload in progress', () => {
+        service.handleAttachmentUpload(binaryFileStateResource);
+
+        expect(service.getUploadAttachmentInProgress()).toBeObservable(
+          singleCold({
+            loading: false,
+            error: binaryFileStateResource.error,
+          } as UploadFileInProgress),
+        );
+      });
+
+      it('should emit binary file', () => {
+        service.handleAttachmentUpload(binaryFileStateResource);
+
+        expect(service.getUploadedAttachment()).toBeObservable(singleCold(binaryFileStateResource));
+      });
+    });
+
+    describe('on success', () => {
+      const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(
+        createBinaryFileResource(),
+      );
+
+      it('should emit upload in progress', () => {
+        service.handleAttachmentUpload(binaryFileStateResource);
+
+        expect(service.getUploadAttachmentInProgress()).toBeObservable(
+          singleCold({
+            loading: false,
+          } as UploadFileInProgress),
+        );
+      });
+
+      it('should emit binary file', () => {
+        service.handleAttachmentUpload(binaryFileStateResource);
+
+        expect(service.getUploadedAttachment()).toBeObservable(singleCold(binaryFileStateResource));
+      });
+    });
+  });
 });
diff --git a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
index 51939bd89281d0a5e4c2971c026cebf8f6ef34ce..1bb8e644829d9f5e7627f8c4aa40b09e2c43e86c 100644
--- a/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
+++ b/alfa-client/libs/bescheid-shared/src/lib/bescheid.service.ts
@@ -42,6 +42,7 @@ import {
   map,
   startWith,
   switchMap,
+  tap,
 } from 'rxjs';
 import {
   ListResourceServiceConfig,
@@ -97,6 +98,13 @@ export class BescheidService {
   readonly uploadBescheidDocumentInProgress$: BehaviorSubject<UploadFileInProgress> =
     new BehaviorSubject<UploadFileInProgress>({ loading: false });
 
+  readonly uploadAttachmentInProgress$: BehaviorSubject<UploadFileInProgress> = new BehaviorSubject(
+    { loading: false },
+  );
+
+  readonly uploadedAttachment$: BehaviorSubject<StateResource<BinaryFileResource>> =
+    new BehaviorSubject(createEmptyStateResource());
+
   loadBescheidDocumentSubscription: Subscription;
 
   constructor(
@@ -143,6 +151,7 @@ export class BescheidService {
     );
     this.bescheidDocumentFile$.next(createEmptyStateResource());
     this.bescheidDocumentUri$.next(null);
+    this.uploadedAttachment$.next(createEmptyStateResource());
   }
 
   public getBescheidDraft(): Observable<StateResource<BescheidResource>> {
@@ -323,10 +332,10 @@ export class BescheidService {
   private clearCreateBescheidDocumentInProgress(): void {
     this.createBescheidDocumentInProgress$.next({ loading: false });
   }
-
   private initUploadBescheidDocumentInProgress(fileName: string): void {
     this.uploadBescheidDocumentInProgress$.next({ fileName, loading: true });
   }
+
   public getUploadBescheidDocumentInProgress(): Observable<UploadFileInProgress> {
     return this.uploadBescheidDocumentInProgress$.asObservable();
   }
@@ -521,4 +530,41 @@ export class BescheidService {
   public refreshList(): void {
     this.bescheidListService.refresh();
   }
+
+  public uploadAttachment(
+    bescheidResource: BescheidResource,
+    file: File,
+  ): Observable<StateResource<BinaryFileResource>> {
+    this.uploadAttachmentInProgress$.next({ fileName: file.name, loading: true });
+    return this.binaryFileService
+      .uploadFile(bescheidResource, BescheidLinkRel.UPLOAD_ATTACHMENT, file, false)
+      .pipe(
+        tap((binaryFileStateResource: StateResource<BinaryFileResource>) =>
+          this.handleAttachmentUpload(binaryFileStateResource),
+        ),
+      );
+  }
+
+  handleAttachmentUpload(binaryFileStateResource: StateResource<BinaryFileResource>) {
+    if (hasError(binaryFileStateResource)) {
+      this.uploadAttachmentInProgress$.next({
+        loading: false,
+        error: binaryFileStateResource.error,
+      });
+    } else {
+      this.uploadAttachmentInProgress$.next({
+        ...this.uploadAttachmentInProgress$.value,
+        loading: binaryFileStateResource.loading,
+      });
+    }
+    this.uploadedAttachment$.next(binaryFileStateResource);
+  }
+
+  public getUploadAttachmentInProgress(): Observable<UploadFileInProgress> {
+    return this.uploadAttachmentInProgress$.asObservable();
+  }
+
+  public getUploadedAttachment(): Observable<StateResource<BinaryFileResource>> {
+    return this.uploadedAttachment$.asObservable();
+  }
 }
diff --git a/alfa-client/libs/design-system/src/lib/attachment/attachment.component.ts b/alfa-client/libs/design-system/src/lib/attachment/attachment.component.ts
index d7587434211166d8695269b96f639025a72a679e..26b8e0b77783d3dd5f6de9ef1eecbdc5c7db1220 100644
--- a/alfa-client/libs/design-system/src/lib/attachment/attachment.component.ts
+++ b/alfa-client/libs/design-system/src/lib/attachment/attachment.component.ts
@@ -24,9 +24,15 @@ import { SpinnerIconComponent } from '../icons/spinner-icon/spinner-icon.compone
       <ods-spinner-icon *ngIf="isLoading && !isError" size="large" />
     </div>
     <div class="flex grow flex-col items-start break-all text-start text-text">
-      <p class="text-sm" [ngClass]="isError && 'text-error'">
+      <p *ngIf="!isError && !isLoading && caption" class="text-sm">
         {{ caption }}
       </p>
+      <p *ngIf="isError && errorCaption" class="text-sm text-error">
+        {{ errorCaption }}
+      </p>
+      <p *ngIf="isLoading && loadingCaption" class="text-sm">
+        {{ loadingCaption }}
+      </p>
       <p *ngIf="description && !isError" class="text-xs text-text/65">
         {{ description }}
       </p>
@@ -38,7 +44,9 @@ import { SpinnerIconComponent } from '../icons/spinner-icon/spinner-icon.compone
   </button>`,
 })
 export class AttachmentComponent {
-  @Input({ required: true }) caption!: string;
+  @Input() caption: string = '';
+  @Input() errorCaption: string = '';
+  @Input() loadingCaption: string = '';
   @Input() fileType: string = '';
   @Input() description = '';
   @Input() isLoading: boolean = false;
diff --git a/alfa-client/libs/tech-shared/test/file.ts b/alfa-client/libs/tech-shared/test/file.ts
index 4664c7c07c48b29995dfbef49dc2a27b7ad9b0f9..3f0fd180a866e86a1f9c2747bfae8b876a19950c 100644
--- a/alfa-client/libs/tech-shared/test/file.ts
+++ b/alfa-client/libs/tech-shared/test/file.ts
@@ -1,3 +1,5 @@
+import { faker } from '@faker-js/faker';
+
 export function createFile(): File {
-  return <any>{};
-}
\ No newline at end of file
+  return <any>{ name: faker.datatype.string(10), type: 'image/png', size: 512 };
+}
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.ts
index f7d6ea59813fa20881d5cb9d019aac71f81e6fef..dc987af324371fbc73cab82d955fa0cb935e9443 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.ts
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/bescheiden.formservice.ts
@@ -14,7 +14,6 @@ import {
   HttpError,
   StateResource,
   convertToBoolean,
-  createEmptyStateResource,
   formatForDatabase,
   isNotEmpty,
   isNotNil,
@@ -37,7 +36,6 @@ import {
   Subscription,
   combineLatest,
   map,
-  of,
   startWith,
 } from 'rxjs';
 
@@ -68,8 +66,6 @@ export class BescheidenFormService extends AbstractFormService implements OnDest
   ].join('\n\n');
 
   private readonly bescheidChanges$: BehaviorSubject<Bescheid>;
-  private attachmentUpload$: BehaviorSubject<StateResource<BinaryFileResource>>;
-  private bescheidFileUpload$: Observable<StateResource<BinaryFileResource>>;
   private readonly fileDelete$: Subject<BinaryFileResource>;
   private readonly showMissingBescheidDocumentError$: BehaviorSubject<boolean> =
     new BehaviorSubject<boolean>(false);
@@ -80,7 +76,6 @@ export class BescheidenFormService extends AbstractFormService implements OnDest
   vorgangWithEingangResource: VorgangWithEingangResource;
 
   private formControlSubscriptions: Subscription;
-
   private formChangesSubscription: Subscription;
 
   constructor(
@@ -96,10 +91,6 @@ export class BescheidenFormService extends AbstractFormService implements OnDest
 
   init(): void {
     this.formControlSubscriptions = this.subscribeToSendBy();
-    this.bescheidFileUpload$ = of(createEmptyStateResource<BinaryFileResource>());
-    this.attachmentUpload$ = new BehaviorSubject<StateResource<BinaryFileResource>>(
-      createEmptyStateResource(),
-    );
     this.initializeFormChanges();
   }
 
@@ -219,22 +210,6 @@ export class BescheidenFormService extends AbstractFormService implements OnDest
     return this.vorgangWithEingangResource;
   }
 
-  public getAttachmentUpload(): Observable<StateResource<BinaryFileResource>> {
-    return this.attachmentUpload$.asObservable();
-  }
-
-  public uploadAttachment(attachment: StateResource<BinaryFileResource>): void {
-    this.attachmentUpload$.next(attachment);
-  }
-
-  public getBescheidFileUpload(): Observable<StateResource<BinaryFileResource>> {
-    return this.bescheidFileUpload$;
-  }
-
-  public setBescheidFileUpload(bescheidFileUpload$: Observable<StateResource<BinaryFileResource>>) {
-    this.bescheidFileUpload$ = bescheidFileUpload$;
-  }
-
   public deleteFile(binaryFileResource: BinaryFileResource): void {
     this.fileDelete$.next(binaryFileResource);
   }
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.html
index 780524bd40f6a2dbba30fdeb83df3c133076bd47..fc9bcf1ed04f5df8d10a3a92d1c6d611d827574f 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.html
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.html
@@ -7,12 +7,6 @@
   >
   </alfa-binary-file2-container>
   <ng-container *ngFor="let attachment of uploadedAttachments">
-    <ods-attachment
-      *ngIf="attachment.error || attachment.loading"
-      [caption]="getAttachmentCaption(attachment)"
-      [error]="attachment.error"
-      [isLoading]="attachment.loading"
-    ></ods-attachment>
     <alfa-binary-file2-container
       *ngIf="!attachment.loading && attachment.resource"
       [file]="attachment.resource"
@@ -22,4 +16,15 @@
     >
     </alfa-binary-file2-container>
   </ng-container>
+  <ng-container *ngIf="uploadInProgress$ | async as uploadFileInProgress">
+    <ods-attachment
+      data-test-id="attachment-upload-in-progress"
+      *ngIf="uploadFileInProgress.loading || uploadFileInProgress.error"
+      [loadingCaption]="uploadFileInProgress.fileName"
+      errorCaption="Fehler beim Hochladen"
+      [error]="uploadFileInProgress.error"
+      description="Anhang wird hochgeladen"
+      [isLoading]="uploadFileInProgress.loading"
+    ></ods-attachment>
+  </ng-container>
 </ods-attachment-container>
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.spec.ts
index b60bd2b3fdc6b623666f52ae0b6ef799e75300f3..1e9ed7dcaa08a8f3a261a01eaf31c317eb00d7ac 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.spec.ts
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.spec.ts
@@ -4,7 +4,6 @@ import { BinaryFileResource } from '@alfa-client/binary-file-shared';
 import {
   convertForDataTest,
   ConvertForDataTestPipe,
-  createEmptyStateResource,
   createErrorStateResource,
   createStateResource,
   FileSizePipe,
@@ -21,6 +20,7 @@ import {
 } from '@ods/system';
 import { MockComponent, MockPipe } from 'ng-mocks';
 import { BehaviorSubject, EMPTY, Observable, of, Subscription } from 'rxjs';
+import { createUploadFileInProgress } from '../../../../../../../bescheid-shared/src/test/bescheid';
 import {
   createBinaryFileResource,
   createLoadedBinaryFileResource,
@@ -41,13 +41,12 @@ describe('VorgangDetailBescheidenResultAttachmentsComponent', () => {
   beforeEach(async () => {
     bescheidService = mock(BescheidService);
     bescheidService.getAttachments.mockReturnValue(EMPTY);
+    bescheidService.getUploadedAttachment.mockReturnValue(EMPTY);
 
     formService = mock(BescheidenFormService);
     formService.getBescheidChanges.mockReturnValue(
       new BehaviorSubject({ beschiedenAm: new Date(), bewilligt: false }),
     );
-    formService.getAttachmentUpload.mockReturnValue(of(createEmptyStateResource()));
-    formService.getBescheidFileUpload.mockReturnValue(of(createEmptyStateResource()));
 
     await TestBed.configureTestingModule({
       declarations: [
@@ -88,6 +87,7 @@ describe('VorgangDetailBescheidenResultAttachmentsComponent', () => {
     const dataTestId = getDataTestIdOf(
       `${convertForDataTest(attachment.resource.name)}-file2-container`,
     );
+    const uploadInProgressDataTestId: string = getDataTestIdOf('attachment-upload-in-progress');
 
     beforeEach(() => {
       component.uploadedAttachments = [attachment];
@@ -115,6 +115,38 @@ describe('VorgangDetailBescheidenResultAttachmentsComponent', () => {
 
       notExistsAsHtmlElement(fixture, dataTestId);
     });
+
+    it('should render attachment in progress component when loading', () => {
+      component.uploadInProgress$ = of({ ...createUploadFileInProgress(), loading: true });
+
+      fixture.detectChanges();
+
+      existsAsHtmlElement(fixture, uploadInProgressDataTestId);
+    });
+
+    it('should render attachment in progress component on error', () => {
+      component.uploadInProgress$ = of({
+        ...createUploadFileInProgress(),
+        loading: false,
+        error: createApiError(),
+      });
+
+      fixture.detectChanges();
+
+      existsAsHtmlElement(fixture, uploadInProgressDataTestId);
+    });
+
+    it('should not render attachment in progress component when not loading and no error', () => {
+      component.uploadInProgress$ = of({
+        ...createUploadFileInProgress(),
+        loading: false,
+        error: null,
+      });
+
+      fixture.detectChanges();
+
+      notExistsAsHtmlElement(fixture, uploadInProgressDataTestId);
+    });
   });
 
   describe('ngOnInit', () => {
@@ -137,6 +169,12 @@ describe('VorgangDetailBescheidenResultAttachmentsComponent', () => {
 
       expect(subscribeToAttachmentUpload).toHaveBeenCalled();
     });
+
+    it('should get upload attachment in progress', () => {
+      component.ngOnInit();
+
+      expect(bescheidService.getUploadAttachmentInProgress).toHaveBeenCalled();
+    });
   });
 
   describe('ngOnDestroy', () => {
@@ -144,7 +182,7 @@ describe('VorgangDetailBescheidenResultAttachmentsComponent', () => {
       const subscription = mock(Subscription);
       const observable = mock(Observable);
       observable.subscribe.mockReturnValue(subscription);
-      formService.getAttachmentUpload.mockReturnValue(observable);
+      bescheidService.getUploadedAttachment.mockReturnValue(observable);
       component.ngOnInit();
 
       component.ngOnDestroy();
@@ -187,13 +225,7 @@ describe('VorgangDetailBescheidenResultAttachmentsComponent', () => {
 
     beforeEach(() => {
       attachment = createLoadedBinaryFileResource();
-      formService.getAttachmentUpload.mockReturnValue(of(attachment));
-    });
-
-    it('should get attachment upload', () => {
-      component.subscribeToAttachmentUpload();
-
-      expect(formService.getAttachmentUpload).toHaveBeenCalled();
+      bescheidService.getUploadedAttachment.mockReturnValue(of(attachment));
     });
 
     it('should should set uploaded attachments', () => {
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.ts
index f8497323adfe75ac2e4bc428775bc7e1c6bc5a0c..2fc7831dfd9a89285b24301ca6a8aa19345f083a 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.ts
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.ts
@@ -1,4 +1,4 @@
-import { BescheidService } from '@alfa-client/bescheid-shared';
+import { BescheidService, UploadFileInProgress } from '@alfa-client/bescheid-shared';
 import { BinaryFileResource } from '@alfa-client/binary-file-shared';
 import {
   StateResource,
@@ -10,7 +10,7 @@ import {
 } from '@alfa-client/tech-shared';
 import { Component, Input, OnDestroy, OnInit } from '@angular/core';
 import { getUrl } from '@ngxp/rest';
-import { Subscription, first } from 'rxjs';
+import { Observable, Subscription, first } from 'rxjs';
 import { BescheidenFormService } from '../../bescheiden.formservice';
 
 @Component({
@@ -23,6 +23,7 @@ export class VorgangDetailBescheidenResultAttachmentsComponent implements OnDest
 
   existingAttachments: BinaryFileResource[] = [];
   uploadedAttachments: StateResource<BinaryFileResource>[] = [];
+  uploadInProgress$: Observable<UploadFileInProgress>;
 
   private attachmentUploadSubscription: Subscription;
 
@@ -32,6 +33,7 @@ export class VorgangDetailBescheidenResultAttachmentsComponent implements OnDest
   ) {}
 
   ngOnInit(): void {
+    this.uploadInProgress$ = this.bescheidService.getUploadAttachmentInProgress();
     this.loadExistingAttachments();
     this.subscribeToAttachmentUpload();
   }
@@ -52,8 +54,8 @@ export class VorgangDetailBescheidenResultAttachmentsComponent implements OnDest
   }
 
   subscribeToAttachmentUpload() {
-    this.attachmentUploadSubscription = this.formService
-      .getAttachmentUpload()
+    this.attachmentUploadSubscription = this.bescheidService
+      .getUploadedAttachment()
       .subscribe(
         (stateResource: StateResource<BinaryFileResource>) =>
           (this.uploadedAttachments = this.buildUploadedAttachments(stateResource)),
@@ -80,16 +82,4 @@ export class VorgangDetailBescheidenResultAttachmentsComponent implements OnDest
       (attachment) => getUrl(attachment) !== getUrl(file),
     );
   }
-
-  getAttachmentCaption(attachment: StateResource<BinaryFileResource>) {
-    if (attachment.loading) {
-      return 'Anhang wird hochgeladen';
-    }
-
-    if (attachment.error) {
-      return 'Fehler beim Hochladen';
-    }
-
-    return attachment.resource.name;
-  }
 }
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.html
index 3148cf1d0d907496b5b4f9164e7c1621a1aa3953..a89c65186da52532a6f73829e58afaaaf65703cd 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.html
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.html
@@ -17,8 +17,11 @@
   </ng-container>
   <ods-attachment
     *ngIf="uploadBescheidDocumentInProgress.loading || uploadBescheidDocumentInProgress.error"
-    [caption]="attachmentCaption"
-    [attr.data-test-id]="attachmentDataTestId"
+    errorCaption="Fehler beim Hochladen"
+    [loadingCaption]="uploadBescheidDocumentInProgress.fileName"
+    [attr.data-test-id]="
+      'upload-bescheid-document-error-' + !!uploadBescheidDocumentInProgress.error
+    "
     [isLoading]="uploadBescheidDocumentInProgress.loading"
     [error]="uploadBescheidDocumentInProgress.error"
   ></ods-attachment>
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.spec.ts
index 5bd0f8b68ece0d217355d957b040611c03259381..2f71e2de6a3ef57174f129655ba0dd7f1c8ddab5 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.spec.ts
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.spec.ts
@@ -17,7 +17,7 @@ describe('VorgangDetailBescheidenResultDokumentComponent', () => {
   let fixture: ComponentFixture<VorgangDetailBescheidenResultDokumentComponent>;
 
   const createBescheidDocumentError: string = getDataTestIdOf('create-bescheid-document-error');
-  const uploadBescheidDocumentError: string = getDataTestIdOf('upload-bescheid-document-error');
+  const uploadBescheidDocumentError: string = getDataTestIdOf('upload-bescheid-document-error-true');
   const missingBescheidDocumentErrorMessage: string = getDataTestIdOf(
     'missing-bescheid-document-error-message',
   );
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.ts
index f6fc855c98546cb0a9d29ac6dbc03f0ddfc62d41..f46d2cbd1d7aa2719a19b7f73ae55e1efb23945e 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.ts
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.ts
@@ -25,30 +25,6 @@ export class VorgangDetailBescheidenResultDokumentComponent {
 
   @Output() deleteFile: EventEmitter<void> = new EventEmitter<void>();
 
-  get attachmentCaption() {
-    if (this.uploadBescheidDocumentInProgress.loading) {
-      return 'Bescheiddokument wird hochgeladen';
-    }
-
-    if (this.uploadBescheidDocumentInProgress.error) {
-      return 'Fehler beim Hochladen';
-    }
-
-    return this.bescheidDocumentFile.resource.name;
-  }
-
-  get attachmentDataTestId() {
-    if (this.uploadBescheidDocumentInProgress.loading) {
-      return 'upload-bescheid-document-loading';
-    }
-
-    if (this.uploadBescheidDocumentInProgress.error) {
-      return 'upload-bescheid-document-error';
-    }
-
-    return 'upload-bescheid-document-file';
-  }
-
   constructor(private bescheidService: BescheidService) {}
 
   handleBescheidDocument(bescheid: BescheidResource): void {
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.spec.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.spec.ts
index c6d4b9f293b55af444bb3a6b3da555bc5e382200..74c2aea0911f06523b5b632206a370f06cba0f15 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.spec.ts
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.spec.ts
@@ -1,16 +1,17 @@
-import { BescheidLinkRel, BescheidResource, BescheidService } from '@alfa-client/bescheid-shared';
+import { BescheidResource, BescheidService } from '@alfa-client/bescheid-shared';
 import { BinaryFileAttachmentContainerComponent } from '@alfa-client/binary-file';
-import { BinaryFileResource, BinaryFileService } from '@alfa-client/binary-file-shared';
-import { createEmptyStateResource, createStateResource } from '@alfa-client/tech-shared';
+import { BinaryFileResource } from '@alfa-client/binary-file-shared';
+import { StateResource, createStateResource } from '@alfa-client/tech-shared';
 import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms';
 import { FileUploadEditorComponent } from '@ods/component';
-import { cold } from 'jest-marbles';
 import { MockComponent } from 'ng-mocks';
 import { EMPTY, Observable, Subscription, of } from 'rxjs';
-import { createBescheidResource } from '../../../../../../../../../bescheid-shared/src/test/bescheid';
+import { createBescheidStateResource } from '../../../../../../../../../bescheid-shared/src/test/bescheid';
 import { createBinaryFileResource } from '../../../../../../../../../binary-file-shared/test/binary-file';
+import { createFile } from '../../../../../../../../../tech-shared/test/file';
+import { singleColdCompleted } from '../../../../../../../../../tech-shared/test/marbles';
 import { BescheidenFormService } from '../../../../bescheiden.formservice';
 import { VorgangDetailBescheidenAttachmentHochladenComponent } from './vorgang-detail-bescheiden-attachment-hochladen.component';
 
@@ -20,15 +21,12 @@ describe('VorgangDetailBescheidenDokumentHochladenComponent', () => {
   const selfLink: string = 'self';
 
   let bescheidService: Mock<BescheidService>;
-  let binaryFileService: Mock<BinaryFileService>;
   let formService: BescheidenFormService;
 
   beforeEach(async () => {
     bescheidService = mock(BescheidService);
     bescheidService.getAttachments.mockReturnValue(EMPTY);
 
-    binaryFileService = mock(BinaryFileService);
-
     formService = new BescheidenFormService(new UntypedFormBuilder(), useFromMock(bescheidService));
 
     await TestBed.configureTestingModule({
@@ -47,10 +45,6 @@ describe('VorgangDetailBescheidenDokumentHochladenComponent', () => {
           provide: BescheidService,
           useValue: bescheidService,
         },
-        {
-          provide: BinaryFileService,
-          useValue: binaryFileService,
-        },
       ],
     }).compileComponents();
 
@@ -167,90 +161,42 @@ describe('VorgangDetailBescheidenDokumentHochladenComponent', () => {
   });
 
   describe('uploadFile', () => {
-    const file: File = <any>{ name: 'TestDatei' };
-    let uploadAndGetFile: jest.Mock;
+    const bescheidDraftStateResource: StateResource<BescheidResource> =
+      createBescheidStateResource();
+    const file: File = createFile();
+    const binaryFileStateResource: StateResource<BinaryFileResource> = createStateResource(
+      createBinaryFileResource(),
+    );
 
     beforeEach(() => {
-      uploadAndGetFile = component.uploadAndGetFile = jest.fn();
+      bescheidService.uploadAttachment.mockReturnValue(of(binaryFileStateResource));
+      component.bescheidDraftStateResource = bescheidDraftStateResource;
     });
 
-    it('should uploadAndGetFile', () => {
-      uploadAndGetFile.mockReturnValue(of(createEmptyStateResource()));
-
+    it('should upload attachment', () => {
       component.uploadFile(file);
 
-      expect(component.uploadAndGetFile).toHaveBeenCalledWith(file);
-    });
-
-    it('should start with loading empty state resource', () => {
-      const loadingStateResource = createEmptyStateResource(true);
-      const uploadStateResource = createStateResource(createBinaryFileResource());
-      uploadAndGetFile.mockReturnValue(cold('-a', { a: uploadStateResource }));
-
-      component.uploadFile(file);
+      component.uploadInProgress$.subscribe();
 
-      expect(component.uploadInProgress$).toBeObservable(
-        cold('ab', { a: loadingStateResource, b: uploadStateResource }),
+      expect(bescheidService.uploadAttachment).toHaveBeenCalledWith(
+        bescheidDraftStateResource.resource,
+        file,
       );
     });
 
-    it('should call form service', () => {
-      formService.uploadAttachment = jest.fn();
-      uploadAndGetFile.mockReturnValue(of(createEmptyStateResource()));
-
+    it('should add to file list', () => {
       component.uploadFile(file);
-      component.uploadInProgress$.subscribe();
 
-      expect(formService.uploadAttachment).toHaveBeenCalledWith(createEmptyStateResource());
-    });
-  });
-
-  describe('uploadAndGetFile', () => {
-    const file: File = <any>{ name: 'TestDatei' };
-    let bescheidResource: BescheidResource;
-    let uploadResource: BinaryFileResource;
-
-    beforeEach(() => {
-      bescheidResource = createBescheidResource();
-      uploadResource = createBinaryFileResource();
-      bescheidService.getBescheidDraft.mockReturnValue(of(createStateResource(bescheidResource)));
-      binaryFileService.uploadFile.mockReturnValue(of(createStateResource(uploadResource)));
-    });
-
-    it('should get bescheid draft', () => {
-      component.uploadAndGetFile(file);
-
-      expect(bescheidService.getBescheidDraft).toHaveBeenCalled();
-    });
-
-    it('should upload file', (done) => {
-      const binaryFileStateResource$ = component.uploadAndGetFile(file);
-
-      binaryFileStateResource$.subscribe(() => {
-        expect(binaryFileService.uploadFile).toHaveBeenCalledWith(
-          bescheidResource,
-          BescheidLinkRel.UPLOAD_ATTACHMENT,
-          file,
-          false,
-        );
-        done();
-      });
-    });
-
-    it('should add file to file list', (done) => {
-      const binaryFileStateResource$ = component.uploadAndGetFile(file);
+      component.uploadInProgress$.subscribe();
 
-      binaryFileStateResource$.subscribe(() => {
-        expect(component.fileList[0]).toEqual(uploadResource);
-        done();
-      });
+      expect(component.fileList).toEqual([binaryFileStateResource.resource]);
     });
 
-    it('should emit binary file state resource', () => {
-      const binaryFileStateResource$ = component.uploadAndGetFile(file);
+    it('should emit', () => {
+      component.uploadFile(file);
 
-      expect(binaryFileStateResource$).toBeObservable(
-        cold('(a|)', { a: createStateResource(uploadResource) }),
+      expect(component.uploadInProgress$).toBeObservable(
+        singleColdCompleted(binaryFileStateResource),
       );
     });
   });
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.ts
index 6632bbe6b17fd5739b97eb99b67f261f1a7bb672..e707f6c2dbcccc73815f858e8adf68726ba57d6a 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.ts
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-attachment-hochladen/vorgang-detail-bescheiden-attachment-hochladen.component.ts
@@ -1,16 +1,14 @@
-import { BescheidLinkRel, BescheidResource, BescheidService } from '@alfa-client/bescheid-shared';
-import { BinaryFileResource, BinaryFileService } from '@alfa-client/binary-file-shared';
+import { BescheidResource, BescheidService } from '@alfa-client/bescheid-shared';
+import { BinaryFileResource } from '@alfa-client/binary-file-shared';
 import {
   StateResource,
   createEmptyStateResource,
   doOnValidStateResource,
-  isLoaded,
   isNotNil,
 } from '@alfa-client/tech-shared';
-import { Component, OnDestroy, OnInit } from '@angular/core';
+import { Component, Input, OnDestroy, OnInit } from '@angular/core';
 import { getUrl } from '@ngxp/rest';
-import { Observable, Subscription, filter, first, of, startWith, switchMap } from 'rxjs';
-import { tap } from 'rxjs/operators';
+import { Observable, Subscription, first, of, tap } from 'rxjs';
 import { BescheidenFormService } from '../../../../bescheiden.formservice';
 
 @Component({
@@ -19,6 +17,8 @@ import { BescheidenFormService } from '../../../../bescheiden.formservice';
   styles: [],
 })
 export class VorgangDetailBescheidenAttachmentHochladenComponent implements OnInit, OnDestroy {
+  @Input() bescheidDraftStateResource: StateResource<BescheidResource>;
+
   uploadInProgress$: Observable<StateResource<BinaryFileResource>>;
   fileList: BinaryFileResource[] = [];
   private deleteFileSubscription: Subscription;
@@ -28,7 +28,6 @@ export class VorgangDetailBescheidenAttachmentHochladenComponent implements OnIn
   constructor(
     public readonly formService: BescheidenFormService,
     private readonly bescheidService: BescheidService,
-    private readonly binaryFileService: BinaryFileService,
   ) {
     this.uploadInProgress$ = of(createEmptyStateResource<BinaryFileResource>());
   }
@@ -63,34 +62,16 @@ export class VorgangDetailBescheidenAttachmentHochladenComponent implements OnIn
     return this.fileList.map((fileResource: BinaryFileResource) => getUrl(fileResource));
   }
 
-  public uploadFile(file: File) {
-    this.uploadInProgress$ = this.uploadAndGetFile(file).pipe(
-      tap((stateResource) => this.formService.uploadAttachment(stateResource)),
-      startWith(createEmptyStateResource<BinaryFileResource>(true)),
-    );
-  }
-
-  uploadAndGetFile(file: File): Observable<StateResource<BinaryFileResource>> {
-    return this.bescheidService.getBescheidDraft().pipe(
-      filter(isLoaded),
-      first(),
-      switchMap((bescheidStateResource: StateResource<BescheidResource>) =>
-        this.binaryFileService
-          .uploadFile(
-            bescheidStateResource.resource,
-            BescheidLinkRel.UPLOAD_ATTACHMENT,
-            file,
-            false,
-          )
-          .pipe(
-            tap((stateResource: StateResource<BinaryFileResource>) =>
-              doOnValidStateResource(
-                stateResource,
-                () => (this.fileList = [...this.fileList, stateResource.resource]),
-              ),
-            ),
+  public uploadFile(file: File): void {
+    this.uploadInProgress$ = this.bescheidService
+      .uploadAttachment(this.bescheidDraftStateResource.resource, file)
+      .pipe(
+        tap((stateResource: StateResource<BinaryFileResource>) =>
+          doOnValidStateResource(
+            stateResource,
+            () => (this.fileList = [...this.fileList, stateResource.resource]),
           ),
-      ),
-    );
+        ),
+      );
   }
 }
diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component.html
index 2c98dc3938883b3658342b7bf8194264c0e3bbbc..2cfc7ff99368dc650ab7807c53c4bc0414d00ea4 100644
--- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component.html
+++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-steps/vorgang-detail-bescheiden-steps-content/vorgang-detail-bescheiden-dokumente-hinzufuegen/vorgang-detail-bescheiden-dokumente-hinzufuegen.component.html
@@ -5,5 +5,7 @@
   <alfa-vorgang-detail-bescheiden-dokument-hochladen
     [bescheidDraftStateResource]="bescheidDraftStateResource$ | async"
   ></alfa-vorgang-detail-bescheiden-dokument-hochladen>
-  <alfa-vorgang-detail-bescheiden-attachment-hochladen></alfa-vorgang-detail-bescheiden-attachment-hochladen>
+  <alfa-vorgang-detail-bescheiden-attachment-hochladen
+    [bescheidDraftStateResource]="bescheidDraftStateResource$ | async"
+  ></alfa-vorgang-detail-bescheiden-attachment-hochladen>
 </div>