SixLabors/ImageSharp · error · InvalidOperationException

Target ICC profile is missing.

Error message

Target ICC profile is missing.

What it means

The same fast-fail check in Convert also requires converter.Options.TargetIccProfile to be set. Without a target profile the converter does not know which color space to transform pixels into, so it throws InvalidOperationException before any processing.

Solutions

  1. Set converter.Options.TargetIccProfile to a valid IccProfile before calling Convert.
  2. Verify the target profile loaded successfully (e.g. from file or embedded resource) before constructing the options.
  3. Choose an explicit well-known target (sRGB, Adobe RGB, etc.) matching your output intent.

Example fix

// before
var options = new ColorConversionOptions { SourceIccProfile = src }; // target missing
// after
var options = new ColorConversionOptions { SourceIccProfile = src, TargetIccProfile = LoadSRgbProfile() };
Defensive patterns

Strategy: validation

Validate before calling

if (converter.Options.TargetIccProfile is null)
{
    throw new InvalidOperationException("Assign a TargetIccProfile before converting.");
}

Type guard

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

Try / catch

try { source.ConvertProfiles(converter); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Target ICC profile is missing")) { /* assign target profile and retry */ }

Prevention

When it happens

Trigger: Calling the ICC conversion extension with ColorConversionOptions.TargetIccProfile left null (source profile set but target forgotten).

Common situations: Copy-pasting converter setup and deleting the target line; dynamically building options where the target profile load from disk failed and returned null; trying to normalize pixels without choosing a destination space.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at src/ImageSharp/ColorProfiles/ColorProfileConverterExtensionsPixelCompatible.cs:49

    /// image.
    /// </param>
    /// <exception cref="InvalidOperationException">
    /// Thrown if the converter's source or target ICC profile is not specified.
    /// </exception>
    public static void Convert<TPixel>(this ColorProfileConverter converter, Image<TPixel> source)
        where TPixel : unmanaged, IPixel<TPixel>
    {
        // These checks actually take place within the converter, but we want to fail fast here.
        // Note. we do not check to see whether the profiles themselves are RGB compatible,
        // if they are not, then the converter will simply produce incorrect results.
        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.");
        }

        // Process the rows in parallel chunks, the converter itself is thread safe.
        source.Mutate(o => o.ProcessPixelRowsAsVector4(
            row =>
            {
                // Gather and convert the pixels in the row to Rgb.
                using IMemoryOwner<Rgb> rgbBuffer = converter.Options.MemoryAllocator.Allocate<Rgb>(row.Length);
                Span<Rgb> rgbSpan = rgbBuffer.Memory.Span;
                Rgb.FromScaledVector4(row, rgbSpan);

                // Perform the actual color conversion.
                converter.ConvertUsingIccProfile<Rgb, Rgb>(rgbSpan, rgbSpan);

                // Copy the converted Rgb pixels back to the row as TPixel.
                // Important: Preserve alpha from the existing row Vector4 values.
                // We merge RGB from rgbSpan into row, leaving W untouched.
                ref float srcRgb = ref Unsafe.As<Rgb, float>(ref MemoryMarshal.GetReference(rgbSpan));

View on GitHub (pinned to 59ce6af6fc)