{"record":{"id":"3b3c5e5c01f0edeb","repo":"immich-app/immich","slug":"unsupported-file-type-filename","errorCode":null,"errorMessage":"Unsupported file type ${filename}","messagePattern":"Unsupported file type (.+?)","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/asset-media.service.ts","lineNumber":88,"sourceCode":"      }\n\n      case UploadFieldName.SIDECAR_DATA: {\n        if (mimeTypes.isSidecar(filename)) {\n          return true;\n        }\n        break;\n      }\n\n      case UploadFieldName.PROFILE_DATA: {\n        if (mimeTypes.isProfile(filename)) {\n          return true;\n        }\n        break;\n      }\n    }\n\n    this.logger.error(`Unsupported file type ${filename}`);\n    throw new BadRequestException(`Unsupported file type ${filename}`);\n  }\n\n  getUploadFilename({ auth, fieldName, file, body }: UploadRequest): string {\n    requireUploadAccess(auth);\n\n    const extension = getFilenameExtension(body.filename || file.originalName);\n    const lookup = {\n      [UploadFieldName.ASSET_DATA]: extension,\n      [UploadFieldName.SIDECAR_DATA]: '.xmp',\n      [UploadFieldName.PROFILE_DATA]: extension,\n    };\n\n    return sanitize(`${file.uuid}${lookup[fieldName]}`);\n  }\n\n  getUploadFolder({ auth, fieldName, file }: UploadRequest): string {\n    auth = requireUploadAccess(auth);\n","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/asset-media.service.ts#L70-L106","documentation":"Thrown by AssetMediaService.canUploadFile when the uploaded file's extension is not recognized as valid for its form field. Each UploadFieldName has its own mime-type gate: ASSET_DATA requires mimeTypes.isAsset, SIDECAR_DATA requires isSidecar, PROFILE_DATA requires isProfile. Falling through the switch with no match logs and throws BadRequestException (HTTP 400).","triggerScenarios":"Multipart POST to /assets with field `assetData` whose filename has a non-asset extension (e.g. .txt, .exe); `sidecarData` field with a non-.xmp file; `file` (profile) field with a non-image type. The filename used is body.filename || file.originalName.","commonSituations":"Client sending a placeholder or temp file; mislabeled extension; new/raw camera format not yet in the supported mime table; uploading a sidecar with the wrong field name.","solutions":["Check the file extension against Immich's supported mime types before uploading","Ensure the correct form field name is used (assetData / sidecarData / file)","Rename mislabeled files to a supported extension, or convert the asset to a supported format","For sidecar uploads, confirm the file is .xmp"],"exampleFix":"// before\nform.append('assetData', fs.createReadStream('scan.txt'));\n// after\nconst SUPPORTED = ['.jpg','.jpeg','.heic','.png','.mov','.mp4','.raw','.dng'/* ... */];\nif (!SUPPORTED.includes(path.extname(file.name).toLowerCase())) throw new Error('unsupported');\nform.append('assetData', fs.createReadStream(file.path));","handlingStrategy":"validation","validationCode":"// Verify file extension against Immich's supported sets before upload\nimport { extname } from 'path';\nconst ASSET = ['.jpg','.jpeg','.png','.heic','.heif','.avif','.webp','.gif','.tif','.tiff','.dng','.raw','.cr2','.arw','.mov','.mp4','.m4v','.webm','.mkv'/* ... */];\nconst SIDECAR = ['.xmp'];\nconst PROFILE = ['.jpg','.jpeg','.png','.webp','.heic','.heif','.avif'];\nfunction allowedFor(field, filename) {\n  const ext = extname(filename).toLowerCase();\n  if (field === 'assetData') return ASSET.includes(ext);\n  if (field === 'sidecarData') return SIDECAR.includes(ext);\n  if (field === 'file') return PROFILE.includes(ext);\n  return false;\n}\nif (!allowedFor(field, file.name)) throw new Error('unsupported file type');","typeGuard":"function isSupportedUpload(field: string, filename: string): boolean {\n  const ext = filename.slice(filename.lastIndexOf('.')).toLowerCase();\n  const sets: Record<string, string[]> = {\n    assetData: ['.jpg','.jpeg','.png','.heic','.mov','.mp4','.dng','.raw'/* ... */],\n    sidecarData: ['.xmp'],\n    file: ['.jpg','.jpeg','.png','.webp'],\n  };\n  return (sets[field] ?? []).includes(ext);\n}","tryCatchPattern":null,"preventionTips":["Validate the extension against the field's supported mime set before opening the upload stream","Use the correct multipart field name per upload kind","Keep the client's supported-extension list in sync with server mimeTypes"],"tags":["upload","mime-type","validation","multipart","nestjs"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}