NewTry MagicWP now - first month free
WordPress troubleshooting

Sorry, this file type is not permitted for security reasons

The upload was rejected before anything was written. Either the extension is not on the allowed list, or the file's contents do not match the extension.

Sorry, this file type is not permitted for security reasons.

Short answer

Check what the file actually is rather than what it is called. WordPress verifies contents against extension, so a renamed file is refused even when its extension is allowed — and that check is protecting you, not obstructing you.

Diagnosis

What causes it, most likely first.

Work down the list. Each check is written to rule its row in or out before you change anything, because the fixes below it are different and a guess costs more than a command.

CauseHow to checkFix
The extension is not in the allowed listCommon formats upload fine and this one does not. SVG, WebP on older versions, and font files are the usual examples.Add the type through the upload_mimes filter, naming both the extension and its MIME type. Add only the formats you need rather than opening the list broadly.
The contents do not match the extensionInspecting the file reports a different type from its name — a PNG saved as .jpg, or a spreadsheet exported as .csv that is really HTML.Convert the file properly instead of renaming it. WordPress compares the real type with the extension precisely to catch this, and overriding the check is the wrong lever.
Multisite restricts uploads network-wideNetwork Admin → Settings lists permitted file types, and the extension is missing from it.Add the extension to the network's list. It is applied in addition to the per-site filter, so a filter alone will not get past it.
SVG is being refused deliberatelyOnly SVG fails, and the file is valid. Core does not allow it by default.Allow it only with sanitisation in place. SVG is XML that can carry script, so an unsanitised upload is a stored cross-site-scripting vector rather than an image.
Walkthrough

Fixing it, step by step.

Commands assume WP-CLI and shell access. Where you have neither, each step says what it is doing so it can be done from the dashboard or over SFTP instead.

  1. Find out what the file really is

    This reads the contents, not the name — the same thing WordPress does.

    file --mime-type -b broken-upload.jpg
  2. See what WordPress currently allows

    The list is filterable, so it can differ from the documented default.

    wp eval 'print_r( get_allowed_mime_types() );' | head -n 30
  3. Allow a specific extra type

    Add this in a small plugin rather than the theme, so it survives a theme change.

    add_filter( 'upload_mimes', function ( $mimes ) {
        $mimes['webp'] = 'image/webp';
        return $mimes;
    } );
  4. Convert rather than rename when types disagree

    Re-encoding produces a file whose contents and extension match, which is what the check is asking for.

    magick input.jpg output.png
  5. Retry and confirm the type was stored

    A successful upload records the MIME type it detected; reading it back confirms the fix took.

    wp post list --post_type=attachment --fields=ID,post_mime_type --posts_per_page=5
On MagicWP

What the platform takes off the list.

The media library and the SFTP account are separate paths to the same webroot, so a designer who needs one unusual format can place it directly without the allowed-types list being widened for every editor on the site. Nothing on the platform requires the contents-versus-extension check to be disabled, which is the shortcut most “allow any file type” snippets take.

FAQ

Questions, answered.

Is it safe to allow SVG uploads?
Only with sanitisation. SVG is XML and can contain script that runs in the context of your domain when the file is opened directly, so an unsanitised SVG from an untrusted contributor is a stored XSS, not an image.
Why is my .csv rejected when CSV is allowed?
Because the contents are not CSV. Exports from spreadsheet tools are often HTML or an Excel format with a .csv name, and the mismatch is exactly what the check catches. Re-export as real comma-separated text.
Should I use ALLOW_UNFILTERED_UPLOADS?
No. It disables the check for every administrator and every upload, which turns one inconvenient file into a standing way to place executable content in the webroot. Allow the specific type instead.
The same file uploaded fine last year. What changed?
Either the allowed list narrowed — a plugin that added the type was removed — or the file was re-saved by a tool that changed its real format while keeping the name.