octobercms/october · error · ApplicationException
backend::lang.media.type_blocked
Error message
backend::lang.media.type_blocked
What it means
MediaLibrary::validateExtension() enforces the extension allow-list from FileDefinitions::get('default_extensions') on every write into the media library. A path whose (lowercased) extension is not in that list — .php, .html, .psd, .heic, or a file with no extension at all — throws backend::lang.media.type_blocked. The docblock is explicit: all write entry points funnel through here so nothing with an arbitrary extension lands in the public media folder.
Source
Thrown at modules/media/classes/MediaLibrary.php:542
throw new ApplicationException(Lang::get('system::lang.media.invalid_path', compact('path')));
}
return $path;
}
/**
* validateExtension enforces the Media Library extension allow-list on a destination
* path. Every write entry point should pass through here so callers cannot drop a file
* with an arbitrary extension into the public media folder.
*/
public static function validateExtension(string $path): void
{
$extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
$allowedFileTypes = FileDefinitions::get('default_extensions');
if (!in_array($extension, $allowedFileTypes)) {
throw new ApplicationException(Lang::get('backend::lang.media.type_blocked'));
}
if (System::checkSafeMode() && in_array($extension, ['less', 'sass', 'scss'])) {
throw new ApplicationException(Lang::get('backend::lang.media.type_blocked'));
}
}
/**
* url is a helper that makes a URL for a media file.
* Ideally the file should be passed as a string but it will try to deal with anything.
* @param string $file
* @return string
*/
public static function url($file)
{
if (is_array($file)) {
$file = array_first($file);
}View on GitHub (pinned to b608633a7e)
Solutions
- Upload/rename to a whitelisted extension — inspect FileDefinitions::get('default_extensions') to see the live list
- Extend the allow-list in the file definitions config if the format is genuinely needed
- Convert assets (avif→jpg/png) or bundle unsupported types as zip if policy forbids the extension
- For custom media writes, call MediaLibrary::validateExtension($path) yourself before writing so the rejection is intentional, not a 500
Example fix
// config/filedefinitions.php — before 'default_extensions' => ['jpg','jpeg','png','gif','svg','webp'], // after — add the formats your users actually need 'default_extensions' => ['jpg','jpeg','png','gif','svg','webp','avif','heic'],
Defensive patterns
Strategy: validation
Validate before calling
$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
if (!in_array($ext, FileDefinitions::get('default_extensions'), true)) {
// reject before the write; the server list is authoritative
return Response::json(['error' => 'Extension not permitted: '.$ext], 422);
} Try / catch
try {
MediaLibrary::validateExtension($destPath);
} catch (ApplicationException $e) {
// handle policy rejection without attempting the write
Log::notice('Blocked media write: '.$destPath);
throw $e;
} Prevention
- Call MediaLibrary::validateExtension() yourself before custom writes into the media folder
- Keep the default_extensions list under review when new formats become mainstream
- Restrict the uploader's accepted extensions to the same list
When it happens
Trigger: Uploading or renaming to an extension outside default_extensions; requests attempting to drop a .php/.phtml file into the public media folder; newer formats (avif, heic) absent from the active definitions; extensionless target names.
Common situations: Users uploading modern image formats the site's definitions predate; attackers probing for executable uploads; custom file_definitions config that trimmed the list; plugin code calling putFile/write without checking the list first.
Related errors
- backend::lang.media.type_blocked
- The file type used is blocked for security reasons.
- cms::lang.cms_object.invalid_file
- cms::lang.cms_object.invalid_file_extension
- editor::lang.filesystem.invalid_path
AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21).
Data as JSON: /api/errors/3a98ee2c31dc43bf.
Report an issue: GitHub.