SixLabors/ImageSharp · error · InvalidOperationException

Source ICC profile is missing.

Error message

Source ICC profile is missing.

What it means

ConvertUsingIccProfile requires both a source and a target ICC profile in converter.Options, but SourceIccProfile was null. ICC-based conversion transforms colors by going device->PCS->device through the profile data, so without a source profile the converter cannot know how to interpret the incoming colors. The library throws InvalidOperationException instead of silently falling back to a default profile.

Solutions

  1. Set options.SourceIccProfile to an IccProfile (e.g. parsed from image.Metadata.IccProfile or a known sRGB profile) before calling ConvertUsingIccProfile.
  2. If the image has an embedded profile, pass it through: new ColorConversionOptions { SourceIccProfile = image.Metadata.IccProfile, TargetIccProfile = ... }.
  3. If no profile is available, use the non-ICC Convert method or assign a bundled standard profile such as sRGB v2 instead.

Example fix

// before
var converter = new ColorProfileConverter(new ColorConversionOptions
{
    TargetIccProfile = adobeRgb
});
var rgb = converter.ConvertUsingIccProfile<Rgb24, Rgb24>(pixel);

// after
var converter = new ColorProfileConverter(new ColorConversionOptions
{
    SourceIccProfile = image.Metadata.IccProfile ?? IccProfileExtensions.CreateSrgbProfile(),
    TargetIccProfile = adobeRgb
});
var rgb = converter.ConvertUsingIccProfile<Rgb24, Rgb24>(pixel);
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

bool HasSourceProfile(ColorProfileConverter c) => c.Options.SourceIccProfile is not null;

Try / catch

try { converter.ConvertUsingIccProfile<TFrom, TTo>(in color); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Source ICC profile is missing"))
{ /* fall back to default profile or non-ICC conversion */ }

Prevention

When it happens

Trigger: Calling any ColorProfileConverterExtensions.ConvertUsingIccProfile<TFrom,TTo> overload (single-value or span) when ColorConversionOptions.SourceIccProfile was never assigned.

Common situations: Constructing a ColorProfileConverter with new ColorConversionOptions() and only setting TargetIccProfile (or neither); decoding an image without an embedded ICC profile and assuming a default source profile is used; refactoring code that previously used the built-in (non-ICC) conversion path.

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/c8ad8469103d8460. Report an issue: GitHub.

Appendix: source

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

    /// </remarks>
    /// <typeparam name="TFrom">The type representing the source color profile. Must implement <see cref="IColorProfile{TFrom}"/>.</typeparam>
    /// <typeparam name="TTo">The type representing the destination color profile. Must implement <see cref="IColorProfile{TTo}"/>.</typeparam>
    /// <param name="converter">The color profile converter configured with source and target ICC profiles.</param>
    /// <param name="source">The color value to convert, defined in the source color profile.</param>
    /// <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.

View on GitHub (pinned to 59ce6af6fc)