SixLabors/ImageSharp · error · InvalidIccProfileException
Curve has to be either
Error message
Curve has to be either "{IccTypeSignature}.{Curve}" or "{IccTypeSignature}.{ParametricCurve}" for LutAToB- and LutBToA-TagDataEntries What it means
This error is thrown while reading an ICC profile's lutAToB or lutBToA tag. Each element of the LUT's pipeline (B curves, matrix, M curves, A curves) must be encoded as either a 'curve' or 'parametricCurve' type tag data entry. If the reader encounters any other type signature (e.g. multiLocalizedUnicode, lut16, or a corrupt signature), it declares the profile invalid and stops.
Solutions
- Re-export or regenerate the ICC profile from the original device or profiling tool with standard curve/parametricCurve elements.
- Verify the profile passes an external validator (e.g. ICC profile verification tools) before loading it with ImageSharp.
- Check the profile file is not truncated - the byte count in the tag table must match actual data length.
- If you control the source profile, use a profile editor (e.g. littleCMS tooling) to rewrite the LUT with curveType elements.
Example fix
// before: blindly parsing any profile byte blob
var profile = new IccProfile(suspectBytes);
// after: validate via try-catch and reject bad profiles
try
{
var profile = new IccProfile(suspectBytes);
}
catch (InvalidIccProfileException ex)
{
logger.LogWarning(ex, "Invalid ICC profile, skipping color correction");
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate profile bytes are non-trivial and wrap parsing
if (iccBytes == null || iccBytes.Length < 128)
throw new InvalidDataException("ICC data too short to be a profile"); Try / catch
try
{
var profile = new IccProfile(iccBytes);
}
catch (InvalidIccProfileException ex)
{
logger.LogWarning(ex, "ICC profile rejected: invalid curve element in LUT tag");
// fall back to default profile or skip color management
} Prevention
- Validate profiles with an ICC conformance tool before bulk processing
- Reject truncated files by checking tag table offsets against file length
- Keep a known-good default profile as fallback
- Log the failing tag signature to identify the offending vendor tool
When it happens
Trigger: Calling the ICC profile parsing API (e.g. new IccProfile(bytes) or IccReader.Read) on a profile whose lutAToBType/lutBToAType tag contains an element with a type signature other than curveType or parametricCurveType, or on a profile whose tag data is truncated/corrupt so the signature bytes decode as an unexpected value.
Common situations: Processing third-party or device-generated ICC profiles that embed unsupported element types inside LUT tags; loading truncated or bit-corrupted profile files; hand-modified profile binaries; profiles from obscure vendors that put non-standard elements in LUT tags.
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
- ICC conversion supports at most four input and output…
- Invalid calculation type
- ICC conversion supports at most four input and output…
- ParametricCurve
- ICC conversion supports at most four tone response curves.
AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13).
Data as JSON: /api/errors/e2baf971ce88e084.
Report an issue: GitHub.
Appendix: source
Thrown at src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Curves.cs:200
}
return new IccSampledCurveElement(entries);
}
/// <summary>
/// Reads curve data
/// </summary>
/// <param name="count">Number of input channels</param>
/// <returns>The curve data</returns>
private IccTagDataEntry[] ReadCurves(int count)
{
IccTagDataEntry[] tdata = new IccTagDataEntry[count];
for (int i = 0; i < count; i++)
{
IccTypeSignature type = this.ReadTagDataEntryHeader();
if (type != IccTypeSignature.Curve && type != 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");
}
if (type == IccTypeSignature.Curve)
{
tdata[i] = this.ReadCurveTagDataEntry();
}
else if (type == IccTypeSignature.ParametricCurve)
{
tdata[i] = this.ReadParametricCurveTagDataEntry();
}
this.AddPadding();
}
return tdata;
}
}View on GitHub (pinned to 59ce6af6fc)