SixLabors/ImageSharp · error · InvalidIccProfileException

Invalid MultiProcessElement type of

Error message

Invalid MultiProcessElement type of {signature}

What it means

The MPE (multiProcessElements) tag is a sequence of process elements each identified by a signature. When reading, a signature the library does not recognize (and does not skip as ACS padding) cannot be decoded, so the reader throws instead of producing an incorrect element.

Solutions

  1. Update to the latest ImageSharp version - newer releases add more MPE signatures.
  2. Rebuild the profile using only standard multiProcessElement types supported by the library.
  3. Flatten or rasterize the transform in the profile authoring tool so exotic MPE types are removed.
  4. Catch the exception and skip color transformation for such profiles.
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    profile = IccReader.Read(stream);
}
catch (InvalidIccProfileException ex) when (ex.Message.Contains("MultiProcessElement"))
{
    logger.LogWarning(ex, "Profile uses unsupported multiProcessElement type");
    // fall back to sRGB or a device link without MPE
}

Prevention

When it happens

Trigger: Reading an mAB / mBA type tag containing a multiProcessElement with a signature outside the set the library implements (e.g. newer AMP-era element types like matrix3x3, color3Array variants not yet supported); corrupt signature bytes.

Common situations: Profiles using extended multi-process elements introduced after the library's implemented subset (calculation/collection/curves/matrix/organization clut, bAcs/eAcs); vendor-specific MPE types; corrupt files.

Related errors


AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13). Data as JSON: /api/errors/a6e901cf323d5323. Report an issue: GitHub.

Appendix: source

Thrown at src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.MultiProcessElement.cs:39

        switch (signature)
        {
            case IccMultiProcessElementSignature.CurveSet:
                return this.ReadCurveSetProcessElement(inChannelCount, outChannelCount);
            case IccMultiProcessElementSignature.Matrix:
                return this.ReadMatrixProcessElement(inChannelCount, outChannelCount);
            case IccMultiProcessElementSignature.Clut:
                return this.ReadClutProcessElement(inChannelCount, outChannelCount);

            // Currently just placeholders for future ICC expansion
            case IccMultiProcessElementSignature.BAcs:
                this.AddIndex(8);
                return new IccBAcsProcessElement(inChannelCount, outChannelCount);
            case IccMultiProcessElementSignature.EAcs:
                this.AddIndex(8);
                return new IccEAcsProcessElement(inChannelCount, outChannelCount);

            default:
                throw new InvalidIccProfileException($"Invalid MultiProcessElement type of {signature}");
        }
    }

    /// <summary>
    /// Reads a CurveSet <see cref="IccMultiProcessElement"/>
    /// </summary>
    /// <param name="inChannelCount">Number of input channels</param>
    /// <param name="outChannelCount">Number of output channels</param>
    /// <returns>The read <see cref="IccCurveSetProcessElement"/></returns>
    public IccCurveSetProcessElement ReadCurveSetProcessElement(int inChannelCount, int outChannelCount)
    {
        IccOneDimensionalCurve[] curves = new IccOneDimensionalCurve[inChannelCount];
        for (int i = 0; i < inChannelCount; i++)
        {
            curves[i] = this.ReadOneDimensionalCurve();
            this.AddPadding();
        }

View on GitHub (pinned to 59ce6af6fc)