immich-app/immich · error · BadRequestException

Unsupported file type ${filename}

Error message

Unsupported file type ${filename}

What it means

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).

Source

Thrown at server/src/services/asset-media.service.ts:88

      }

      case UploadFieldName.SIDECAR_DATA: {
        if (mimeTypes.isSidecar(filename)) {
          return true;
        }
        break;
      }

      case UploadFieldName.PROFILE_DATA: {
        if (mimeTypes.isProfile(filename)) {
          return true;
        }
        break;
      }
    }

    this.logger.error(`Unsupported file type ${filename}`);
    throw new BadRequestException(`Unsupported file type ${filename}`);
  }

  getUploadFilename({ auth, fieldName, file, body }: UploadRequest): string {
    requireUploadAccess(auth);

    const extension = getFilenameExtension(body.filename || file.originalName);
    const lookup = {
      [UploadFieldName.ASSET_DATA]: extension,
      [UploadFieldName.SIDECAR_DATA]: '.xmp',
      [UploadFieldName.PROFILE_DATA]: extension,
    };

    return sanitize(`${file.uuid}${lookup[fieldName]}`);
  }

  getUploadFolder({ auth, fieldName, file }: UploadRequest): string {
    auth = requireUploadAccess(auth);

View on GitHub (pinned to 199723261c)

Solutions

  1. Check the file extension against Immich's supported mime types before uploading
  2. Ensure the correct form field name is used (assetData / sidecarData / file)
  3. Rename mislabeled files to a supported extension, or convert the asset to a supported format
  4. For sidecar uploads, confirm the file is .xmp

Example fix

// before
form.append('assetData', fs.createReadStream('scan.txt'));
// after
const SUPPORTED = ['.jpg','.jpeg','.heic','.png','.mov','.mp4','.raw','.dng'/* ... */];
if (!SUPPORTED.includes(path.extname(file.name).toLowerCase())) throw new Error('unsupported');
form.append('assetData', fs.createReadStream(file.path));
Defensive patterns

Strategy: validation

Validate before calling

// Verify file extension against Immich's supported sets before upload
import { extname } from 'path';
const ASSET = ['.jpg','.jpeg','.png','.heic','.heif','.avif','.webp','.gif','.tif','.tiff','.dng','.raw','.cr2','.arw','.mov','.mp4','.m4v','.webm','.mkv'/* ... */];
const SIDECAR = ['.xmp'];
const PROFILE = ['.jpg','.jpeg','.png','.webp','.heic','.heif','.avif'];
function allowedFor(field, filename) {
  const ext = extname(filename).toLowerCase();
  if (field === 'assetData') return ASSET.includes(ext);
  if (field === 'sidecarData') return SIDECAR.includes(ext);
  if (field === 'file') return PROFILE.includes(ext);
  return false;
}
if (!allowedFor(field, file.name)) throw new Error('unsupported file type');

Type guard

function isSupportedUpload(field: string, filename: string): boolean {
  const ext = filename.slice(filename.lastIndexOf('.')).toLowerCase();
  const sets: Record<string, string[]> = {
    assetData: ['.jpg','.jpeg','.png','.heic','.mov','.mp4','.dng','.raw'/* ... */],
    sidecarData: ['.xmp'],
    file: ['.jpg','.jpeg','.png','.webp'],
  };
  return (sets[field] ?? []).includes(ext);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of immich-app/immich@199723261c (2026-08-12). Data as JSON: /api/errors/3b3c5e5c01f0edeb. Report an issue: GitHub.