gitroomhq/postiz-app · error · Error
Unsupported file type.
Error message
Unsupported file type.
What it means
simpleUpload in r2.uploader.ts sniffs the buffer and requires the detected MIME to be one of the values in ALLOWED_EXT_TO_MIME before uploading to R2. It's the same content-based allow-list pattern used across the upload stack, keyed off an extension-to-MIME map.
Source
Thrown at libraries/nestjs-libraries/src/upload/r2.uploader.ts:89
return completeMultipartUpload(req, res);
case 'list-parts':
return listParts(req, res);
case 'abort-multipart-upload':
return abortMultipartUpload(req, res);
case 'sign-part':
return signPart(req, res);
}
return res.status(404).end();
}
export async function simpleUpload(
data: Buffer,
originalFilename: string,
_contentType: string
) {
const detected = await fileTypeFromBuffer(data);
if (!detected || !Object.values(ALLOWED_EXT_TO_MIME).includes(detected.mime)) {
throw new Error('Unsupported file type.');
}
const fileExtension = `.${detected.ext}`;
const safeContentType = detected.mime;
const randomFilename = generateRandomString() + fileExtension;
const params = {
Bucket: CLOUDFLARE_BUCKETNAME,
Key: randomFilename,
Body: data,
ContentType: safeContentType,
};
const command = new PutObjectCommand({ ...params });
await R2.send(command);
return CLOUDFLARE_BUCKET_URL + '/' + randomFilename;
}
View on GitHub (pinned to 0f1647f749)
Solutions
- Sniff the buffer yourself (fileTypeFromBuffer) and log detected.mime to see what's rejected
- Add the MIME value to ALLOWED_EXT_TO_MIME if it should be accepted
- Fix the upstream producer that's emitting unexpected bytes (e.g. an API returning an error page instead of media)
- Keep ALLOWED_EXT_TO_MIME in sync with ALLOWED_MIME_TYPES used elsewhere
Example fix
// before
await simpleUpload(buffer, 'clip.mov', 'video/quicktime'); // mov not in map -> throws
// after
const ALLOWED_EXT_TO_MIME = { ..., mov: 'video/quicktime', ... };
await simpleUpload(buffer, 'clip.mov', 'video/quicktime'); Defensive patterns
Strategy: validation
Validate before calling
import { fileTypeFromBuffer } from 'file-type';
const t = await fileTypeFromBuffer(data);
if (!t || !Object.values(ALLOWED_EXT_TO_MIME).includes(t.mime)) {
throw new Error(`simpleUpload rejects ${t?.mime ?? 'unknown'}`);
} Type guard
const isSimpleUploadable = async (b: Buffer) => { const t = await fileTypeFromBuffer(b); return !!t && Object.values(ALLOWED_EXT_TO_MIME).includes(t.mime); }; Try / catch
try { await simpleUpload(buf, name, ct); } catch (e) { if ((e as Error).message === 'Unsupported file type.') logRejectedBuffer(buf); else throw e; } Prevention
- Sniff before uploading in new call sites
- Keep ALLOWED_EXT_TO_MIME synced with other allow-lists
- Log detected MIME on rejection
When it happens
Trigger: Passing a buffer whose sniffed MIME isn't in ALLOWED_EXT_TO_MIME (svg, text, pdf, heic, unknown signature), an empty buffer, or a mismatch where the filename extension suggests one type but bytes say another.
Common situations: New upload call sites (downloads from provider APIs, generated files) forgetting the type map; ffmpeg/ffmpeg-less pipelines emitting containers not in the map; allow-list drift between this map and the ones in cloudflare.storage.ts / custom.upload.validation.ts.
Related errors
- Unsupported file type.
- Unsupported file type.
- Unsupported file type.
- Unsupported file type.
- Failed to fetch URL
AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27).
Data as JSON: /api/errors/90b8de8db2c26ead.
Report an issue: GitHub.