nopSolutions/nopCommerce · error · Exception

Only zip archives are supported (*.zip)

Error message

Only zip archives are supported (*.zip)

What it means

Thrown by UploadService.UploadIconsArchiveAsync when the uploaded archive file's extension is not '.zip'. The check uses _fileProvider.GetFileExtension on archivefile.FileName and throws a plain Exception if it does not case-insensitively equal '.zip'. The file is never written or extracted, so no partial state is left behind.

Source

Thrown at src/Libraries/Nop.Services/Plugins/UploadService.cs:371

        return descriptors;
    }

    /// <summary>
    /// Upload favicon and app icons
    /// </summary>
    /// <param name="archivefile">Archive file which contains a set of special icons for different OS and devices</param>
    /// <returns>A task that represents the asynchronous operation</returns>
    public virtual async Task UploadIconsArchiveAsync(IFormFile archivefile)
    {
        ArgumentNullException.ThrowIfNull(archivefile);

        var zipFilePath = string.Empty;
        try
        {
            //only zip archives are supported
            if (!_fileProvider.GetFileExtension(archivefile.FileName)?.Equals(".zip", StringComparison.InvariantCultureIgnoreCase) ?? true)
                throw new Exception("Only zip archives are supported (*.zip)");

            //check if there is a folder for favicon and app icons for the current store (all store icons folders are in wwwroot/icons and are called icons_{storeId})
            var storeIconsPath = _fileProvider.GetAbsolutePath(string.Format(NopCommonDefaults.FaviconAndAppIconsPath, await _storeContext.GetActiveStoreScopeConfigurationAsync()));

            CreateDirectory(storeIconsPath);

            zipFilePath = _fileProvider.Combine(storeIconsPath, archivefile.FileName);
            await using (var fileStream = new FileStream(zipFilePath, FileMode.Create))
                await archivefile.CopyToAsync(fileStream);

            await ZipFile.ExtractToDirectoryAsync(zipFilePath, storeIconsPath);
        }
        finally
        {
            //delete the zip file and leave only unpacked files in the folder
            if (!string.IsNullOrEmpty(zipFilePath))
                _fileProvider.DeleteFile(zipFilePath);
        }

View on GitHub (pinned to 64bdf2ff08)

Solutions

  1. Re-package the icons directory as a genuine .zip archive and upload it again.
  2. Verify the file extension in the OS before uploading (rename to .zip only if it truly is a zip).
  3. If integrating programmatically, ensure the multipart form file has a FileName ending in '.zip'.

Example fix

// before: uploading any archive type
// after: re-export the folder as a real .zip, e.g.
//   zip -r icons.zip icons_folder/
// then upload icons.zip
Defensive patterns

Strategy: validation

Validate before calling

var ext = Path.GetExtension(archivefile?.FileName);
if (!string.Equals(ext, ".zip", StringComparison.OrdinalIgnoreCase))
    // show user-facing message, do not call UploadIconsArchiveAsync
    return BadRequest("A .zip archive is required.");

Type guard

static bool IsValidZip(IFormFile f) =>
    f is not null &&
    string.Equals(Path.GetExtension(f.FileName), ".zip", StringComparison.OrdinalIgnoreCase);

Try / catch

try { await _uploadService.UploadIconsArchiveAsync(file); }
catch (Exception ex) when (ex.Message.Contains("*.zip"))
{ ModelState.AddModelError("file", "Upload a .zip archive."); }

Prevention

When it happens

Trigger: An admin uploads a favicon/app-icons archive (e.g. icons.rar, icons.7z, icons.tar.gz, or an extensionless file) through the store icons upload UI. Also triggers when archivefile.FileName is null/has no extension, because GetFileExtension returns null and the null-coalesce forces the branch to true.

Common situations: Browser packaging a folder as a non-zip archive; user re-zipping on macOS produces a '.zip' correctly but Windows 'Send to > Compressed' sometimes yields a .zip with nested folder; uploading a renamed file with a wrong extension; mobile browsers stripping/altering the extension.

Related errors


AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13). Data as JSON: /api/errors/a558226f99e647b0. Report an issue: GitHub.