nopSolutions/nopCommerce · error · NopException
Cannot decode picture binary (file name: {fileName})
Error message
Cannot decode picture binary (file name: {fileName}) What it means
Thrown by PictureService.ValidatePictureAsync, which wraps the entire image decode+resize in try/catch. It decodes the binary via SkiaSharp (SKCodec/SKBitmap.Decode) and resizes if it exceeds MaximumImageSize. Any exception from decode/resizing is rethrown as NopException with the file name. The root cause is inside the inner exception — typically an unsupported/corrupt image format.
Source
Thrown at src/Libraries/Nop.Services/Media/PictureService.cs:1030
using var input = new MemoryStream(pictureBinary);
using var codec = SKCodec.Create(input);
image = AutoOrient(SKBitmap.Decode(codec), codec.EncodedOrigin);
}
else
image = SKBitmap.Decode(pictureBinary);
//resize the image in accordance with the maximum size
if (Math.Max(image.Height, image.Width) <= _mediaSettings.MaximumImageSize)
return Task.FromResult(pictureBinary);
var format = GetImageFormatByMimeType(mimeType);
pictureBinary = ImageResize(image, format, _mediaSettings.MaximumImageSize);
return Task.FromResult(pictureBinary);
}
catch (Exception exc)
{
throw new NopException($"Cannot decode picture binary (file name: {fileName})", exc);
}
}
/// <summary>
/// Get product picture (for shopping cart and order details pages)
/// </summary>
/// <param name="product">Product</param>
/// <param name="attributesXml">Attributes (in XML format)</param>
/// <returns>
/// A task that represents the asynchronous operation
/// The task result contains the picture
/// </returns>
public virtual async Task<Picture> GetProductPictureAsync(Product product, string attributesXml)
{
ArgumentNullException.ThrowIfNull(product);
//first, try to get product attribute combination picture
var combination = await _productAttributeParser.FindProductAttributeCombinationAsync(product, attributesXml);
View on GitHub (pinned to 64bdf2ff08)
Solutions
- Inspect the inner exception (exc) for the exact SkiaSharp error and the true cause.
- Validate the file is a real image of a supported type (JPEG/PNG/GIF/BMP/WebP) before uploading.
- Re-save/convert the source image to a supported format and retry.
- Ensure the deployed SkiaSharp native binaries match the runtime platform so codecs load.
- Reject zero-length or undersized uploads at the client/API boundary.
Example fix
// before
public virtual Task<byte[]> ValidatePictureAsync(byte[] pictureBinary, string mimeType, string fileName)
{
try { /* decode + resize */ }
catch (Exception exc)
{
throw new NopException($"Cannot decode picture binary (file name: {fileName})", exc);
}
}
// after - pre-validate before decoding
if (pictureBinary is null || pictureBinary.Length == 0)
throw new NopException($"Empty picture binary (file name: {fileName})");
using var probe = new MemoryStream(pictureBinary);
using var codec = SKCodec.Create(probe);
if (codec is null)
throw new NopException($"Unsupported image format (file name: {fileName})"); Defensive patterns
Strategy: validation
Validate before calling
// Validate the binary is a decodable image of a supported type before ValidatePictureAsync
if (pictureBinary is null || pictureBinary.Length == 0)
return Error($"Empty picture binary (file name: {fileName})");
using var probe = new MemoryStream(pictureBinary);
using var codec = SKCodec.Create(probe);
if (codec is null || !_supportedMimes.Contains(codec.EncodedFormat.ToString().ToLower()))
return Error($"Unsupported or corrupt image (file name: {fileName})"); Type guard
static bool IsDecodableImage(byte[] bytes)
{
if (bytes is null || bytes.Length == 0) return false;
try { using var ms = new MemoryStream(bytes); return SKCodec.Create(ms) is not null; }
catch { return false; }
} Try / catch
try { var validated = await _pictureService.ValidatePictureAsync(binary, mime, fileName); }
catch (NopException ex) when (ex.Message.StartsWith("Cannot decode picture binary"))
{ /* inspect ex.InnerException for the SkiaSharp cause; reject the upload with a user-facing message */ } Prevention
- Reject zero-length and wrong-extension uploads at the API boundary.
- Limit uploads to supported formats (JPEG/PNG/GIF/BMP/WebP).
- Keep the SkiaSharp native binaries matched to the runtime platform.
- Log the inner exception to diagnose corrupt or unsupported files.
When it happens
Trigger: Uploading a file whose bytes are not a decodable image (wrong MIME type, corrupt file, unsupported codec such as certain TIFF/HEIF, or a zero-length file) so SKBitmap.Decode/SKCodec.Create throws.
Common situations: User uploads a renamed non-image (e.g. .jpg that is actually a PDF); truncated/corrupt upload; SkiaSharp build lacking the codec for the format; very large image causing decode failure; empty stream.
Related errors
- Admin.Common.UploadFile
- Email is not valid.
- {titleRequiredLocale} (localized, formatted with languageNam
- {textRequiredLocale} (localized, formatted with languageName
- No worksheet found
AI-assisted analysis of nopSolutions/nopCommerce@64bdf2ff08 (2026-08-13).
Data as JSON: /api/errors/9ce2e07c76c70a77.
Report an issue: GitHub.