diff --git a/src/components/AttachmentPicker/index.native.tsx b/src/components/AttachmentPicker/index.native.tsx
index f0e618a66124..076b44e5feb8 100644
--- a/src/components/AttachmentPicker/index.native.tsx
+++ b/src/components/AttachmentPicker/index.native.tsx
@@ -19,6 +19,7 @@ import useStyleUtils from '@hooks/useStyleUtils';
 import useTheme from '@hooks/useTheme';
 import useThemeStyles from '@hooks/useThemeStyles';
 import {cleanFileName, resizeImageIfNeeded, showCameraPermissionsAlert, verifyFileFormat} from '@libs/fileDownload/FileUtils';
+import Log from '@libs/Log';
 import CONST from '@src/CONST';
 import type {TranslationPaths} from '@src/languages/types';
 import type {FileObject, ImagePickerResponse as FileResponse} from '@src/types/utils/Attachment';
@@ -219,7 +220,9 @@ function AttachmentPicker({
                                                 checkAllProcessed();
                                             })
                                             .catch((error: Error) => {
-                                                showGeneralAlert(error.message ?? 'An unknown error occurred');
+                                                Log.warn('Failed to convert HEIC image, falling back to original', {error: error.message});
+                                                const fallbackAsset = processAssetWithFallbacks(asset);
+                                                processedAssets.push(fallbackAsset);
                                                 checkAllProcessed();
                                             });
                                     } else {
diff --git a/src/hooks/useFilesValidation.tsx b/src/hooks/useFilesValidation.tsx
index fc3506f97008..b55e59acc470 100644
--- a/src/hooks/useFilesValidation.tsx
+++ b/src/hooks/useFilesValidation.tsx
@@ -146,12 +146,13 @@ function useFilesValidation(onFilesValidated: (files: FileObject[], dataTransfer
             });
     };
 
-    const convertHeicImageToJpegPromise = (file: FileObject): Promise<FileObject> => {
-        return new Promise((resolve, reject) => {
+    const convertHeicToProcessableImagePromise = (file: FileObject): Promise<FileObject> => {
+        return new Promise((resolve) => {
             convertHeicImage(file, {
                 onSuccess: (convertedFile) => resolve(convertedFile),
-                onError: (nonConvertedFile) => {
-                    reject(nonConvertedFile);
+                onError: (_error, originalFile) => {
+                    Log.warn('HEIC conversion failed, falling back to original file', {fileName: file.name});
+                    resolve(originalFile);
                 },
             });
         });
@@ -218,7 +219,7 @@ function useFilesValidation(onFilesValidated: (files: FileObject[], dataTransfer
                 if (otherFiles.some((file) => hasHeicOrHeifExtension(file))) {
                     setIsLoaderVisible(true);
 
-                    return Promise.all(otherFiles.map((file) => convertHeicImageToJpegPromise(file))).then((convertedImages) => {
+                    return Promise.all(otherFiles.map((file) => convertHeicToProcessableImagePromise(file))).then((convertedImages) => {
                         for (const [index, convertedFile] of convertedImages.entries()) {
                             updateFileOrderMapping(otherFiles.at(index), convertedFile);
                         }
diff --git a/src/libs/cropOrRotateImage/index.native.ts b/src/libs/cropOrRotateImage/index.native.ts
index f418d4d3358b..41091c25ba04 100644
--- a/src/libs/cropOrRotateImage/index.native.ts
+++ b/src/libs/cropOrRotateImage/index.native.ts
@@ -1,26 +1,85 @@
-import {manipulateAsync} from 'expo-image-manipulator';
+import {ImageManipulator} from 'expo-image-manipulator';
+import {Platform} from 'react-native';
 import RNFetchBlob from 'react-native-blob-util';
+import ImageSize from 'react-native-image-size';
+import Log from '@libs/Log';
 import getSaveFormat from './getSaveFormat';
 import type {CropOrRotateImage} from './types';
 
 /**
- * Crops and rotates the image on ios/android
+ * Crops and rotates the image on ios/android.
+ * On iOS, falls back to the original unprocessed image if manipulation fails
+ * (e.g. CGContext allocation failure on 48MP photos).
  */
 const cropOrRotateImage: CropOrRotateImage = (uri, actions, options) =>
-    new Promise((resolve) => {
+    new Promise((resolve, reject) => {
         const format = getSaveFormat(options.type);
-        // We need to remove the base64 value from the result, as it is causing crashes on Release builds.
-        // More info: https://github.com/Expensify/App/issues/37963#issuecomment-1989260033
-        manipulateAsync(uri, actions, {compress: options.compress, format}).then(({base64, ...result}) => {
-            RNFetchBlob.fs.stat(result.uri.replace('file://', '')).then(({size}) => {
-                resolve({
-                    ...result,
-                    size,
-                    type: options.type || 'image/jpeg',
-                    name: options.name || 'fileName.jpg',
-                });
+        const context = ImageManipulator.manipulate(uri);
+        for (const action of actions) {
+            if ('crop' in action) {
+                context.crop(action.crop);
+            } else if ('rotate' in action) {
+                context.rotate(action.rotate);
+            }
+        }
+        context
+            .renderAsync()
+            .then((imageRef) => imageRef.saveAsync({compress: options.compress, format}))
+            // We need to remove the base64 value from the result, as it is causing crashes on Release builds.
+            // More info: https://github.com/Expensify/App/issues/37963#issuecomment-1989260033
+            .then(({base64, ...result}) => {
+                RNFetchBlob.fs
+                    .stat(result.uri.replace('file://', ''))
+                    .then(({size}) => {
+                        resolve({
+                            ...result,
+                            size,
+                            type: options.type || 'image/jpeg',
+                            name: options.name || 'fileName.jpg',
+                        });
+                    })
+                    .catch(reject);
+            })
+            .catch((error) => {
+                if (Platform.OS !== 'ios') {
+                    reject(error);
+                    return;
+                }
+
+                Log.warn('Error cropping/rotating image, falling back to original', {error: error instanceof Error ? error.message : String(error)});
+                const filePath = uri.replace('file://', '');
+                ImageSize.getSize(uri)
+                    .then(({width, height}) => {
+                        RNFetchBlob.fs
+                            .stat(filePath)
+                            .then(({size}) => {
+                                resolve({
+                                    uri,
+                                    width: width ?? 0,
+                                    height: height ?? 0,
+                                    size,
+                                    type: options.type || 'image/jpeg',
+                                    name: options.name || 'fileName.jpg',
+                                });
+                            })
+                            .catch(reject);
+                    })
+                    .catch(() => {
+                        RNFetchBlob.fs
+                            .stat(filePath)
+                            .then(({size}) => {
+                                resolve({
+                                    uri,
+                                    width: 0,
+                                    height: 0,
+                                    size,
+                                    type: options.type || 'image/jpeg',
+                                    name: options.name || 'fileName.jpg',
+                                });
+                            })
+                            .catch(reject);
+                    });
             });
-        });
     });
 
 export default cropOrRotateImage;
diff --git a/src/libs/cropOrRotateImage/index.ts b/src/libs/cropOrRotateImage/index.ts
index 1b669999a1ee..4a7a6c76b55a 100644
--- a/src/libs/cropOrRotateImage/index.ts
+++ b/src/libs/cropOrRotateImage/index.ts
@@ -1,19 +1,32 @@
-import {manipulateAsync} from 'expo-image-manipulator';
+import {ImageManipulator} from 'expo-image-manipulator';
 import getSaveFormat from './getSaveFormat';
 import type {CropOrRotateImage} from './types';
 
 const cropOrRotateImage: CropOrRotateImage = (uri, actions, options) =>
-    new Promise((resolve) => {
+    new Promise((resolve, reject) => {
         const format = getSaveFormat(options.type);
-        manipulateAsync(uri, actions, {compress: options.compress, format}).then((result) => {
-            fetch(result.uri)
-                .then((res) => res.blob())
-                .then((blob) => {
-                    const file = new File([blob], options.name || 'fileName.jpeg', {type: options.type || 'image/jpeg'});
-                    file.uri = URL.createObjectURL(file);
-                    resolve(file);
-                });
-        });
+        const context = ImageManipulator.manipulate(uri);
+        for (const action of actions) {
+            if ('crop' in action) {
+                context.crop(action.crop);
+            } else if ('rotate' in action) {
+                context.rotate(action.rotate);
+            }
+        }
+        context
+            .renderAsync()
+            .then((imageRef) => imageRef.saveAsync({compress: options.compress, format}))
+            .then((result) =>
+                fetch(result.uri)
+                    .then((res) => res.blob())
+                    .then((blob) => {
+                        const file = new File([blob], options.name || 'fileName.jpeg', {type: options.type || 'image/jpeg'});
+                        file.uri = URL.createObjectURL(file);
+                        resolve(file);
+                    })
+                    .catch(reject),
+            )
+            .catch(reject);
     });
 
 export default cropOrRotateImage;
diff --git a/src/libs/fileDownload/heicConverter/index.native.ts b/src/libs/fileDownload/heicConverter/index.native.ts
index eaa6776c5f07..34a9ad3001d4 100644
--- a/src/libs/fileDownload/heicConverter/index.native.ts
+++ b/src/libs/fileDownload/heicConverter/index.native.ts
@@ -1,5 +1,6 @@
 import {ImageManipulator, SaveFormat} from 'expo-image-manipulator';
 import {verifyFileFormat} from '@libs/fileDownload/FileUtils';
+import Log from '@libs/Log';
 import CONST from '@src/CONST';
 import type {FileObject} from '@src/types/utils/Attachment';
 import type {HeicConverterFunction} from './types';
@@ -41,7 +42,7 @@ const convertImageWithManipulator = (
             onSuccess(convertedFile);
         })
         .catch((err) => {
-            console.error('Error converting HEIC/HEIF to JPEG:', err);
+            Log.warn('Error converting HEIC/HEIF to JPEG', {error: err instanceof Error ? err.message : String(err)});
             onError(err, file);
         })
         .finally(() => {
@@ -103,7 +104,7 @@ const convertHeicImage: HeicConverterFunction = (file, {onSuccess = () => {}, on
             onSuccess(file);
         })
         .catch((err) => {
-            console.error('Error processing the file:', err);
+            Log.warn('Error processing the file', {error: err instanceof Error ? err.message : String(err)});
             onError(err, file);
         })
         .finally(() => {
