{"record":{"id":"068f9809783489e0","repo":"immich-app/immich","slug":"unable-to-process-profile-image","errorCode":null,"errorMessage":"Unable to process profile image","messagePattern":"Unable to process profile image","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/user.service.ts","lineNumber":118,"sourceCode":"    const user = await this.findOrFail(id, { withDeleted: false });\n    return mapUser(user);\n  }\n\n  async createProfileImage(auth: AuthDto, file: Express.Multer.File): Promise<CreateProfileImageResponseDto> {\n    const { profileImagePath: oldPath } = await this.findOrFail(auth.user.id, { withDeleted: false });\n\n    let profileImagePath: string;\n    try {\n      const config = await this.getConfig({ withCache: true });\n      profileImagePath = await generateProfileImage(\n        { media: this.mediaRepository, crypto: this.cryptoRepository, storageCore: this.storageCore },\n        config,\n        auth.user.id,\n        file.path,\n      );\n    } catch (error) {\n      await this.jobRepository.queue({ name: JobName.FileDelete, data: { files: [file.path] } });\n      throw new BadRequestException('Unable to process profile image', { cause: error });\n    }\n\n    const user = await this.userRepository.update(auth.user.id, {\n      profileImagePath,\n      profileChangedAt: new Date(),\n    });\n\n    const toDelete = [file.path, ...(oldPath ? [oldPath] : [])];\n    await this.jobRepository.queue({ name: JobName.FileDelete, data: { files: toDelete } });\n\n    return {\n      userId: user.id,\n      profileImagePath: user.profileImagePath,\n      profileChangedAt: user.profileChangedAt,\n    };\n  }\n\n  async deleteProfileImage(auth: AuthDto): Promise<void> {","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/services/user.service.ts#L100-L136","documentation":"createProfileImage fails when the uploaded profile image cannot be processed (resizing/conversion pipeline throws). The service queues a FileDelete job to remove the uploaded temp file and wraps the underlying error as a 400 Bad Request with 'Unable to process profile image', preserving the original cause.","triggerScenarios":"POST /users/profile-image with a file whose processing (via config, userId, file.path into the profile image pipeline) throws — e.g. corrupt image, unsupported format, truncated upload, or processing-library failure.","commonSituations":"Uploading a file renamed to .jpg that is not actually an image; uploading HEIC/AVIF on a build without the required decoder libraries; zero-byte or interrupted downloads; images exceeding processing limits.","solutions":["Inspect the `cause` of the error / server logs to see the underlying processing failure (decode error, unsupported format, etc.).","Re-upload a valid, standard JPEG or PNG file that opens in an image viewer.","Convert unsupported formats (HEIC, etc.) to JPEG/PNG before uploading.","On self-hosted servers, ensure required image codec libraries (e.g. libvips/heif) are installed in the container.","Retry after confirming the upload completed fully (check file size, stable connection)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const isValidImage = (file: File) =>\n  file.size > 0 && ['image/jpeg', 'image/png', 'image/webp'].includes(file.type);\nif (!isValidImage(file)) throw new Error('upload a valid JPEG/PNG/WebP image');","typeGuard":"const isImageFile = (f: unknown): f is File & { type: 'image/jpeg' | 'image/png' | 'image/webp' } =>\n  f instanceof File && /^image\\/(jpeg|png|webp)$/.test(f.type);","tryCatchPattern":"try {\n  await api.createProfileImage(file);\n} catch (e) {\n  if (e instanceof BadRequestException && e.message === 'Unable to process profile image') {\n    logger.warn('profile image rejected', { cause: e.cause });\n    // fall back / ask user for a different file\n  }\n}","preventionTips":["Validate MIME type and non-zero size before upload.","Convert HEIC/AVIF to JPEG client-side before uploading.","Verify the image opens in a viewer/library before sending.","Ensure the server image has required codec libraries installed."],"tags":["image-processing","profile-image","upload","bad-request"],"backgroundTag":"file-read-failed","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}