gitroomhq/postiz-app · error · Error

Unsupported file type.

Error message

Unsupported file type.

What it means

Thrown by CloudflareStorage.uploadSimple when the fetched/uploaded buffer's magic-byte sniffing (file-type's fileTypeFromBuffer) fails or produces a MIME type not in ALLOWED_MIME_TYPES (jpeg, png, gif, webp, avif, bmp, tiff, mp4 video, mpeg/mp4/wav/ogg audio). Content is detected from bytes, not from file extension or Content-Type header, so mislabeled files are rejected.

Source

Thrown at libraries/nestjs-libraries/src/upload/cloudflare.storage.ts:98

  async uploadSimple(path: string) {
    const dataUrl = path.startsWith('data:') ? parseDataUrl(path) : null;

    let body: Buffer;
    if (dataUrl) {
      body = dataUrl.buffer;
    } else {
      if (!(await isSafePublicHttpsUrl(path))) {
        throw new Error('Unsafe URL');
      }
      const loadImage = await fetch(path, {
        // @ts-ignore — undici option, not in lib.dom fetch types
        dispatcher: ssrfSafeDispatcher,
      });
      body = Buffer.from(await loadImage.arrayBuffer());
    }
    const detected = await fileTypeFromBuffer(body);
    if (!detected || !ALLOWED_MIME_TYPES.has(detected.mime)) {
      throw new Error('Unsupported file type.');
    }
    const extension = detected.ext;
    const safeContentType = detected.mime;
    const id = makeId(10);

    const params = {
      Bucket: this._bucketName,
      Key: `${id}.${extension}`,
      Body: body,
      ContentType: safeContentType,
      ChecksumMode: 'DISABLED',
    };

    const command = new PutObjectCommand({ ...params });
    await this._client.send(command);

    return `${this._uploadUrl}/${id}.${extension}`;
  }

View on GitHub (pinned to 0f1647f749)

Solutions

  1. Convert the asset to an allowed type before upload (e.g. HEIC→jpeg, mov→mp4, svg→png)
  2. If fetching a remote URL, verify it actually returns the media bytes (curl -I) and not an HTML page
  3. Extend ALLOWED_MIME_TYPES only after reviewing security implications (SVG especially enables XSS)
  4. Check the buffer is non-empty and not corrupted before calling uploadSimple

Example fix

// before
await storage.uploadSimple('https://example.com/photo.heic'); // throws Unsupported file type.

// after — convert first, or validate before upload
import filetype from 'magic-bytes.js'; // or convert with sharp:
import sharp from 'sharp';
const jpeg = await sharp('photo.heic').jpeg().toBuffer();
await storage.uploadSimple(`data:image/jpeg;base64,${jpeg.toString('base64')}`);
Defensive patterns

Strategy: validation

Validate before calling

import { fromBuffer } from 'file-type';

const detected = await fromBuffer(buffer);
const ALLOWED = new Set(['image/jpeg','image/png','image/gif','image/webp','image/avif','image/bmp','image/tiff','video/mp4','audio/mpeg','audio/mp4','audio/wav','audio/ogg']);
if (!detected || !ALLOWED.has(detected.mime)) {
  throw new BadRequestException(`File type ${detected?.mime ?? 'unknown'} is not supported`);
}

Type guard

async function isAllowedMediaBuffer(buf: Buffer): Promise<boolean> {
  const t = await fromBuffer(buf);
  return !!t && ALLOWED.has(t.mime);
}

Try / catch

try {
  await storage.uploadSimple(path);
} catch (e) {
  if (e instanceof Error && e.message === 'Unsupported file type.') {
    return res.status(415).send('Unsupported file type. Allowed: jpeg, png, gif, webp, avif, bmp, tiff, mp4, mpeg, wav, ogg');
  }
  throw e;
}

Prevention

When it happens

Trigger: Uploading an SVG, PDF, HEIC, text file, or any format outside the allowlist; uploading an HTML error page returned instead of an image because the URL returned 200 with a soft error; an empty/corrupt buffer; a data: URL whose base64 decodes to an unsupported type.

Common situations: Users uploading iPhone HEIC photos, SVGs, PDFs, or .mov/.webm videos; a remote URL returning an HTML login/captcha page that is fetched as the 'image'; truncated uploads producing undetectable buffers.

Related errors


AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27). Data as JSON: /api/errors/869816758ba35107. Report an issue: GitHub.