{"record":{"id":"a558226f99e647b0","repo":"nopSolutions/nopCommerce","slug":"only-zip-archives-are-supported-zip","errorCode":null,"errorMessage":"Only zip archives are supported (*.zip)","messagePattern":"Only zip archives are supported \\(\\*\\.zip\\)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Libraries/Nop.Services/Plugins/UploadService.cs","lineNumber":371,"sourceCode":"\n        return descriptors;\n    }\n\n    /// <summary>\n    /// Upload favicon and app icons\n    /// </summary>\n    /// <param name=\"archivefile\">Archive file which contains a set of special icons for different OS and devices</param>\n    /// <returns>A task that represents the asynchronous operation</returns>\n    public virtual async Task UploadIconsArchiveAsync(IFormFile archivefile)\n    {\n        ArgumentNullException.ThrowIfNull(archivefile);\n\n        var zipFilePath = string.Empty;\n        try\n        {\n            //only zip archives are supported\n            if (!_fileProvider.GetFileExtension(archivefile.FileName)?.Equals(\".zip\", StringComparison.InvariantCultureIgnoreCase) ?? true)\n                throw new Exception(\"Only zip archives are supported (*.zip)\");\n\n            //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})\n            var storeIconsPath = _fileProvider.GetAbsolutePath(string.Format(NopCommonDefaults.FaviconAndAppIconsPath, await _storeContext.GetActiveStoreScopeConfigurationAsync()));\n\n            CreateDirectory(storeIconsPath);\n\n            zipFilePath = _fileProvider.Combine(storeIconsPath, archivefile.FileName);\n            await using (var fileStream = new FileStream(zipFilePath, FileMode.Create))\n                await archivefile.CopyToAsync(fileStream);\n\n            await ZipFile.ExtractToDirectoryAsync(zipFilePath, storeIconsPath);\n        }\n        finally\n        {\n            //delete the zip file and leave only unpacked files in the folder\n            if (!string.IsNullOrEmpty(zipFilePath))\n                _fileProvider.DeleteFile(zipFilePath);\n        }","sourceCodeStart":353,"sourceCodeEnd":389,"githubUrl":"https://github.com/nopSolutions/nopCommerce/blob/64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2/src/Libraries/Nop.Services/Plugins/UploadService.cs#L353-L389","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-package the icons directory as a genuine .zip archive and upload it again.","Verify the file extension in the OS before uploading (rename to .zip only if it truly is a zip).","If integrating programmatically, ensure the multipart form file has a FileName ending in '.zip'."],"exampleFix":"// before: uploading any archive type\n// after: re-export the folder as a real .zip, e.g.\n//   zip -r icons.zip icons_folder/\n// then upload icons.zip","handlingStrategy":"validation","validationCode":"var ext = Path.GetExtension(archivefile?.FileName);\nif (!string.Equals(ext, \".zip\", StringComparison.OrdinalIgnoreCase))\n    // show user-facing message, do not call UploadIconsArchiveAsync\n    return BadRequest(\"A .zip archive is required.\");","typeGuard":"static bool IsValidZip(IFormFile f) =>\n    f is not null &&\n    string.Equals(Path.GetExtension(f.FileName), \".zip\", StringComparison.OrdinalIgnoreCase);","tryCatchPattern":"try { await _uploadService.UploadIconsArchiveAsync(file); }\ncatch (Exception ex) when (ex.Message.Contains(\"*.zip\"))\n{ ModelState.AddModelError(\"file\", \"Upload a .zip archive.\"); }","preventionTips":["Validate the extension client-side before upload.","Document that only .zip is accepted in the upload UI label.","Generate zip archives server-side from uploaded directories instead of trusting user extension."],"tags":["plugins","upload","file-extension","validation","zip"],"backgroundTag":null,"analyzedSha":"64bdf2ff08c8b39e65717bcf974fb43dc2ef68f2","analyzedAt":"2026-08-13T21:19:38.062Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}