SixLabors/ImageSharp · error · InvalidOperationException

Target ICC profile is missing.

Error message

Target ICC profile is missing.

What it means

ConvertUsingIccProfile requires a destination ICC profile, but converter.Options.TargetIccProfile was null. After mapping colors into the Profile Connection Space via the source profile, the converter needs the target profile to map PCS values into the destination device space; without it the conversion is undefined, so the library throws.

Solutions

  1. Assign options.TargetIccProfile to a valid IccProfile describing the destination color space.
  2. For standard sRGB output, load/embed a known sRGB ICC profile as the target.
  3. If you do not actually need ICC conversion, use the non-ICC ColorProfileConverter.Convert API.

Example fix

// before
var options = new ColorConversionOptions { SourceIccProfile = image.Metadata.IccProfile };
var converter = new ColorProfileConverter(options);
converter.ConvertUsingIccProfile<Rgb24, CieLab>(pixel);

// after
var options = new ColorConversionOptions
{
    SourceIccProfile = image.Metadata.IccProfile,
    TargetIccProfile = srgbProfile
};
var converter = new ColorProfileConverter(options);
converter.ConvertUsingIccProfile<Rgb24, CieLab>(pixel);
Defensive patterns

Strategy: validation

Validate before calling

if (converter.Options.TargetIccProfile is null)
    throw new InvalidOperationException("Set TargetIccProfile before ICC conversion.");

Type guard

bool HasTargetProfile(ColorProfileConverter c) => c.Options.TargetIccProfile is not null;

Try / catch

try { converter.ConvertUsingIccProfile<TFrom, TTo>(in color); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Target ICC profile is missing"))
{ /* configure a target profile and retry */ }

Prevention

When it happens

Trigger: Calling ConvertUsingIccProfile when ColorConversionOptions.TargetIccProfile was never assigned (with or without SourceIccProfile set).

Common situations: Building options incrementally and forgetting the target; intending 'keep colors as-is' but still selecting the ICC path; copying configuration code and dropping the TargetIccProfile line.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsIcc.cs:75

    /// <returns>
    /// A color value in the target color profile, resulting from the ICC profile-based conversion of the source value.
    /// </returns>
    /// <exception cref="InvalidOperationException">
    /// Thrown if either the source or target ICC profile is missing from the converter options.
    /// </exception>
    internal static TTo ConvertUsingIccProfile<TFrom, TTo>(this ColorProfileConverter converter, in TFrom source)
        where TFrom : struct, IColorProfile<TFrom>
        where TTo : struct, IColorProfile<TTo>
    {
        // TODO: Validation of ICC Profiles against color profile. Is this possible?
        if (converter.Options.SourceIccProfile is null)
        {
            throw new InvalidOperationException("Source ICC profile is missing.");
        }

        if (converter.Options.TargetIccProfile is null)
        {
            throw new InvalidOperationException("Target ICC profile is missing.");
        }

        ConversionParams sourceParams = new(converter.Options.SourceIccProfile, toPcs: true);
        ConversionParams targetParams = new(converter.Options.TargetIccProfile, toPcs: false);

        ColorProfileConverter pcsConverter = new(new ColorConversionOptions
        {
            MemoryAllocator = converter.Options.MemoryAllocator,
            SourceWhitePoint = KnownIlluminants.D50Icc,
            TargetWhitePoint = KnownIlluminants.D50Icc
        });

        // Normalize the source, then convert to the PCS space.
        Vector4 sourcePcs = sourceParams.Converter.Calculate(source.ToScaledVector4());

        // If both profiles need PCS adjustment, they both share the same unadjusted PCS space
        // cancelling out the need to make the adjustment
        // except if using TRC transforms, which always requires perceptual handling

View on GitHub (pinned to 59ce6af6fc)