SixLabors/ImageSharp · error · InvalidIccProfileException
Curve has to be either "IccTypeSignature.Curve" or…
Error message
Curve has to be either "IccTypeSignature.Curve" or "IccTypeSignature.ParametricCurve" for LutAToB- and LutBToA-TagDataEntries
What it means
ImageSharp's ICC profile writer requires that every curve in a LutAToB or LutBToA tag data entry has a type signature of either Curve or ParametricCurve. When writing such an entry, WriteCurves iterates the curve list and throws InvalidIccProfileException if any entry has another signature (e.g. a multiLocalizedUnicode or text entry accidentally placed in the curve list).
Solutions
- Inspect the curves arrays on the LutAtoB/LutBToA entry and remove or replace any entry whose Signature is not Curve or ParametricCurve
- Convert curve data into a proper IccCurveTagDataEntry or IccParametricCurveTagDataEntry before assigning it to the entry
- If the profile came from an external source, re-export it from a conformant tool so the Lut tag contains only curve entries
- Wrap ICC writing in a try-catch on InvalidIccProfileException to surface a clear message about the offending entry
Example fix
// before
var entry = new IccLutAtoBTagDataEntry(..., curvesB: new IccTagDataEntry[] { someTextEntry });
// after
var curveEntry = new IccCurveTagDataEntry(curveData);
var entry = new IccLutAtoBTagDataEntry(..., curvesB: new IccTagDataEntry[] { curveEntry }); Defensive patterns
Strategy: validation
Validate before calling
bool valid = entry.CurvesM?.All(c => c.Signature is IccTypeSignature.Curve or IccTypeSignature.ParametricCurve) ?? true
&& (entry.CurvesA?.All(c => c.Signature is IccTypeSignature.Curve or IccTypeSignature.ParametricCurve) ?? true)
&& (entry.CurvesB?.All(c => c.Signature is IccTypeSignature.Curve or IccTypeSignature.ParametricCurve) ?? true); Type guard
static bool IsCurveEntry(IccTagDataEntry e) => e.Signature is IccTypeSignature.Curve or IccTypeSignature.ParametricCurve;
Try / catch
try { writer.WriteTagDataEntry(lutEntry); } catch (InvalidIccProfileException ex) { log.Error(ex, "Non-curve entry in Lut tag"); throw; } Prevention
- Only build LutAtoB/BToA curves arrays from IccCurveTagDataEntry or IccParametricCurveTagDataEntry
- Validate every entry's Signature before assignment
- Round-trip test profiles you parse from external sources before re-serializing
When it happens
Trigger: Calling WriteTagDataEntry on an IccLutAtoBTagDataEntry or IccLutBToATagDataEntry whose ATobB curves collection (curvesM, curvesA, or curvesB) contains an entry whose IccTagDataEntry.Signature is not IccTypeSignature.Curve or IccTypeSignature.ParametricCurve.
Common situations: Hand-constructing ICC LutAtoB/BToA entries with a mis-typed entry in the curves arrays; parsing a non-conformant ICC profile and re-serializing it; copying entries from one profile's tag table into another's Lut curves list.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Unrecognized colorant encoding
- Source ICC profile is missing.
- Target ICC profile is missing.
- Source PCS to target PCS is not supported
- Source PCS is not supported
AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13).
Data as JSON: /api/errors/b8a823ce7d7e8b9b.
Report an issue: GitHub.
Appendix: source
Thrown at src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.cs:220
this.dataStream.WriteByte(data[i]);
}
return length;
}
/// <summary>
/// Writes curve data
/// </summary>
/// <param name="curves">The curves to write</param>
/// <returns>The number of bytes written</returns>
private int WriteCurves(IccTagDataEntry[] curves)
{
int count = 0;
foreach (IccTagDataEntry curve in curves)
{
if (curve.Signature != IccTypeSignature.Curve && curve.Signature != IccTypeSignature.ParametricCurve)
{
throw new InvalidIccProfileException($"Curve has to be either \"{nameof(IccTypeSignature)}.{nameof(IccTypeSignature.Curve)}\" or" +
$" \"{nameof(IccTypeSignature)}.{nameof(IccTypeSignature.ParametricCurve)}\" for LutAToB- and LutBToA-TagDataEntries");
}
count += this.WriteTagDataEntry(curve);
count += this.WritePadding();
}
return count;
}
private void Dispose(bool disposing)
{
if (!this.isDisposed)
{
if (disposing)
{
this.dataStream?.Dispose();
}View on GitHub (pinned to 59ce6af6fc)