MonoGame/MonoGame · error · ArgumentException
ETC1 bitmap with width {Width} and height {Height} needs {by
Error message
ETC1 bitmap with width {Width} and height {Height} needs {bytesRequired} bytes. Received {sourceData?.Length ?? 0} bytes What it means
Etc1BitmapContent.SetPixelData validates that the supplied byte buffer exactly matches the ETC1 footprint: ((Width+3)>>2)*((Height+3)>>2) blocks times the RgbEtc1 block size (8 bytes per 4x4 block, padded up). A mismatch means the data cannot be a valid ETC1 encoding of a bitmap this size, so it rejects the write with the expected vs received sizes.
Source
Thrown at MonoGame.Framework.Content.Pipeline/Graphics/Etc1BitmapContent.cs:42
/// <summary>
/// Initializes a new instance of Etc1BitmapContent with the specified width or height.
/// </summary>
/// <param name="width">Width in pixels of the bitmap resource.</param>
/// <param name="height">Height in pixels of the bitmap resource.</param>
public Etc1BitmapContent(int width, int height) : base(width, height)
{
}
/// <inheritdoc/>
public override byte[] GetPixelData() => _data;
/// <inheritdoc/>
public override void SetPixelData(byte[]? sourceData)
{
var bytesRequired = ((Width + 3) >> 2) * ((Height + 3) >> 2) * SurfaceFormat.RgbEtc1.GetSize();
if (bytesRequired != (sourceData?.Length ?? 0))
{
throw new ArgumentException($"ETC1 bitmap with width {Width} and height {Height} needs {bytesRequired} bytes. Received {sourceData?.Length ?? 0} bytes");
}
if (sourceData == null || sourceData.Length == 0)
{
_data = [];
return;
}
if (_data == null || _data.Length != bytesRequired)
{
_data = new byte[bytesRequired];
}
Buffer.BlockCopy(sourceData, 0, _data, 0, bytesRequired);
}
/// <inheritdoc/>
protected override bool TryCopyFrom(BitmapContent sourceBitmap, Rectangle sourceRegion, Rectangle destinationRegion)View on GitHub (pinned to 1d71bbd0ff)
Solutions
- Allocate the Etc1BitmapContent with the same width/height as the source texture.
- Pre-compute bytesRequired = ((W+3)>>2)*((H+3)>>2)*SurfaceFormat.RgbEtc1.GetSize() and supply exactly that many bytes.
- Ensure you pass the ETC1-encoded block data, not raw RGBA.
Example fix
// before etc1.SetPixelData(rawRgbaBytes); // wrong size // after int need = ((W+3)>>2) * ((H+3)>>2) * SurfaceFormat.RgbEtc1.GetSize(); byte[] encoded = Etc1Encoder.Encode(rawRgbaBytes, W, H); Debug.Assert(encoded.Length == need); etc1.SetPixelData(encoded);
Defensive patterns
Strategy: validation
Validate before calling
int need = ((etc1.Width + 3) >> 2) * ((etc1.Height + 3) >> 2) * SurfaceFormat.RgbEtc1.GetSize();
if ((data?.Length ?? 0) != need)
throw new ArgumentException($"Expected {need} ETC1 bytes, got {data?.Length ?? 0}.");
etc1.SetPixelData(data); Type guard
null
Try / catch
null
Prevention
- Match bitmap dimensions to the source texture.
- Pass ETC1-encoded block data, never raw RGBA.
When it happens
Trigger: Calling SetPixelData with a buffer whose length is not the exact ETC1 block-padded byte count for the bitmap's Width/Height; e.g. feeding raw RGBA, feeding DXT/ETC2 bytes, or wrong width/height on the bitmap.
Common situations: Mismatched source texture dimensions vs. the Etc1BitmapContent dimensions; passing uncompressed pixel data to a compressed bitmap; off-by-block-padding errors in a custom ETC encoder output.
Related errors
- Invalid block size
- ETC2 bitmap with width {Width} and height {Height} needs {by
- DxtBitmapContent cannot compress format=[{format}]
- Could not retrieve surface format of source bitmap
- Could not retrieve surface format of destination bitmap
AI-assisted analysis of MonoGame/MonoGame@1d71bbd0ff (2026-08-13).
Data as JSON: /api/errors/4d239119bff95237.
Report an issue: GitHub.