SixLabors/ImageSharp · error · InvalidIccProfileException
Invalid CLUT data type of
Error message
Invalid CLUT data type of {value.DataType} What it means
When writing a CLUT, its DataType must be UInt8, UInt16, or Float32. The writer switches on the declared data type to pick the binary encoding; an unknown IccClutDataType has no on-disk representation, so the writer refuses instead of emitting garbage bytes.
Solutions
- Set the IccClut DataType explicitly to IccClutDataType.UInt8, UInt16, or Float32 before writing.
- Initialize IccClut via a constructor that takes the data and channel counts so DataType is derived correctly.
- Check for invalid enum casts into IccClutDataType in your code path.
Example fix
// before: struct default leaves DataType unset
count += writer.WriteClut(new IccClut());
// after: construct with valid data and matching channel counts
var clut = new IccClut(
inChannelCount: 3,
outChannelCount: 3,
gridPointCount: new byte[] { 2, 2, 2 },
IccClutDataType.Float32,
values); Defensive patterns
Strategy: validation
Validate before calling
// Verify DataType before writing
if (clut.DataType is not (IccClutDataType.UInt8 or IccClutDataType.UInt16 or IccClutDataType.Float32))
throw new ArgumentException("CLUT DataType must be UInt8, UInt16, or Float32"); Try / catch
try { writer.WriteClut(clut); }
catch (InvalidIccProfileException ex) when (ex.Message.Contains("CLUT data type"))
{
// re-initialize clut with explicit, valid DataType
clut = RecreateClutWithValidDataType(clut);
writer.WriteClut(clut);
} Prevention
- Construct IccClut with constructors that derive DataType from the value array
- Avoid raw enum casts into IccClutDataType
- Never use default(IccClut) in generated profiles
- Round-trip only fully parsed profiles
When it happens
Trigger: Calling WriteClut (via WriteClutProcessElement / WriteLutAtoBTagDataEntry / WriteLutBToATagDataEntry) with an IccClut whose DataType property is an undefined/invalid IccClutDataType value (e.g. default-initialized struct or manually cast value).
Common situations: Programmatic ICC profile generation with a partially initialized IccClut; deserializing a CLUT from an unsupported profile and re-serializing without fixing DataType; enum casts from ints out of range.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid CLUT size of
- Invalid CLUT dimensions.
- The CLUT data is shorter than its declared dimensions.
- Invalid CurveSegment type of
- Invalid MultiProcessElement type of
AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13).
Data as JSON: /api/errors/7e28447fa5f54b4f.
Report an issue: GitHub.
Appendix: source
Thrown at src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Lut.cs:65
{
int count = this.WriteArray(value.GridPointCount);
count += this.WriteEmpty(16 - value.GridPointCount.Length);
switch (value.DataType)
{
case IccClutDataType.Float:
return count + this.WriteClutF32(value);
case IccClutDataType.UInt8:
count += this.WriteByte(1);
count += this.WriteEmpty(3);
return count + this.WriteClut8(value);
case IccClutDataType.UInt16:
count += this.WriteByte(2);
count += this.WriteEmpty(3);
return count + this.WriteClut16(value);
default:
throw new InvalidIccProfileException($"Invalid CLUT data type of {value.DataType}");
}
}
/// <summary>
/// Writes a 8bit color lookup table.
/// </summary>
/// <param name="value">The CLUT to write.</param>
/// <returns>The number of bytes written.</returns>
public int WriteClut8(IccClut value)
{
int count = 0;
foreach (float item in value.Values)
{
count += this.WriteByte((byte)Numerics.Clamp((item * byte.MaxValue) + 0.5F, 0, byte.MaxValue));
}
return count;
}View on GitHub (pinned to 59ce6af6fc)