SixLabors/ImageSharp · error · ImageFormatException
TGA image does not have a valid format.
Error message
TGA image does not have a valid format.
What it means
TgaDecoderCore.Decode wraps its whole decode in a catch for IndexOutOfRangeException and rethrows it as ImageFormatException with 'TGA image does not have a valid format.' This converts out-of-bounds reads caused by inconsistent TGA header/field data (offsets, color-map sizes, pixel counts that run past the buffer) into a clean format error with the original exception as InnerException. It signals the byte stream does not match any TGA layout the decoder can navigate safely.
Solutions
- Open the InnerException/stack to see which read went out of bounds, then inspect the TGA header (18 bytes) with a hex editor for implausible dimensions or color-map values.
- Re-export the image in a well-formed TGA (or convert to PNG) from the original source.
- Verify the file size matches what the producer wrote; re-transfer if truncated.
- Catch ImageFormatException and treat the input as invalid/unreadable rather than retrying.
Example fix
// before
using var image = Image.Load("legacy.tga");
// after
try
{
using var image = Image.Load("legacy.tga");
}
catch (ImageFormatException ex)
{
Console.WriteLine($"Invalid TGA: {ex.Message} (root: {ex.InnerException?.Message})");
} Defensive patterns
Strategy: try-catch
Validate before calling
// Sanity-check the 18-byte TGA header before decode.
byte[] h = new byte[18];
using (var fs = File.OpenRead(path)) if (fs.Read(h, 0, 18) != 18) throw new InvalidDataException("Too short for TGA header.");
int width = h[12] | (h[13] << 8), height = h[14] | (h[15] << 8);
int depth = h[16];
if (width <= 0 || height <= 0 || depth is not (8 or 15 or 16 or 24 or 32))
throw new InvalidDataException("Suspicious TGA header."); Try / catch
try { using var img = Image.Load(path); }
catch (ImageFormatException ex)
{
// InnerException holds the underlying IndexOutOfRangeException
Log(ex.InnerException ?? ex, "TGA does not have a valid format.");
} Prevention
- Inspect InnerException to pinpoint which TGA field ran out of bounds.
- Re-export legacy TGAs into a modern format before processing.
- Verify file completeness against expected sizes for uploaded TGAs.
- Prefer PNG over TGA for interchange when you control the pipeline.
When it happens
Trigger: Image.Load/Image.Identify on a TGA file whose declared header fields (width/height, color-map length/offset, pixel depth) cause row or color-map indexing to exceed the actual data — i.e. data shorter than the header promises.
Common situations: Truncated TGA files from interrupted uploads; TGA variants from old/obscure tools with nonstandard field layouts; renaming non-TGA files to .tga; fuzzed or corrupted images.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid . . Was ' '.
- Invalid or . . Was ' ' and ' '.
- {errorMessage}
- The ANI sequence references a missing frame resource.
- The ANI file does not contain any decodable animation steps.
AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13).
Data as JSON: /api/errors/97a42a73e23e293d.
Report an issue: GitHub.
Appendix: source
Thrown at src/ImageSharp/Formats/Tga/TgaDecoderCore.cs:200
this.ReadRle(stream, this.fileHeader.Width, this.fileHeader.Height, pixels, 4, origin);
}
else
{
this.ReadBgra32(stream, this.fileHeader.Width, this.fileHeader.Height, pixels, origin);
}
break;
default:
TgaThrowHelper.ThrowNotSupportedException("ImageSharp does not support this kind of tga files.");
break;
}
return image;
}
catch (IndexOutOfRangeException e)
{
throw new ImageFormatException("TGA image does not have a valid format.", e);
}
}
/// <summary>
/// Reads a uncompressed TGA image with a palette.
/// </summary>
/// <typeparam name="TPixel">The pixel type.</typeparam>
/// <param name="stream">The <see cref="BufferedReadStream"/> containing image data.</param>
/// <param name="width">The width of the image.</param>
/// <param name="height">The height of the image.</param>
/// <param name="pixels">The <see cref="Buffer2D{TPixel}"/> to assign the palette to.</param>
/// <param name="palette">The color palette.</param>
/// <param name="colorMapPixelSizeInBytes">Color map size of one entry in bytes.</param>
/// <param name="origin">The image origin.</param>
private void ReadPaletted<TPixel>(BufferedReadStream stream, int width, int height, Buffer2D<TPixel> pixels, Span<byte> palette, int colorMapPixelSizeInBytes, TgaImageOrigin origin)
where TPixel : unmanaged, IPixel<TPixel>
{
bool invertX = InvertX(origin);View on GitHub (pinned to 59ce6af6fc)