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

  1. Allocate the Etc1BitmapContent with the same width/height as the source texture.
  2. Pre-compute bytesRequired = ((W+3)>>2)*((H+3)>>2)*SurfaceFormat.RgbEtc1.GetSize() and supply exactly that many bytes.
  3. 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

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


AI-assisted analysis of MonoGame/MonoGame@1d71bbd0ff (2026-08-13). Data as JSON: /api/errors/4d239119bff95237. Report an issue: GitHub.