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

  1. Re-export or regenerate the ICC profile from the original device or profiling tool with standard curve/parametricCurve elements.
  2. Verify the profile passes an external validator (e.g. ICC profile verification tools) before loading it with ImageSharp.
  3. Check the profile file is not truncated - the byte count in the tag table must match actual data length.
  4. 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

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


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)