dotnet/wpf · error · NotSupportedException

Transform identifier type is not supported.

Error message

Transform identifier type is not supported.

What it means

DataSpaceManager.InstantiateDataTransformObject only supports transform identifier types equal to TransformIdentifierTypes_PredefinedTransformName. When deserializing a stored transform definition whose transformClassType field has any other value, a NotSupportedException with SR.TransformTypeUnsupported is thrown. The library deliberately supports no reflection-based construction of arbitrary transform classes, only a small set of predefined transforms.

Solutions

  1. Rewrite the file so its transforms are stored with the predefined-transform-name identifier type (e.g. re-save the package without the exotic transform).
  2. Strip the unsupported transform from the package using a tool that rewrites the data space info, then reopen the file.
  3. Pre-check the transform identifier type bytes in the DataSpaceInfo stream before loading and reject the file with a clear custom message.
  4. Catch NotSupportedException during package open and fall back to a read-only/no-transform handling path or surface 'file uses unsupported transform' to the user.

Example fix

// before
var package = Package.Open(path); // throws NotSupportedException on odd transform id type
// after
try { var package = Package.Open(path); }
catch (NotSupportedException)
{
    throw new InvalidDataException("Package uses a transform identifier type not supported by this runtime.");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// inspect transform identifier type bytes in the DataSpaceInfo stream before loading
int idType = ReadInt32At(transformInfoOffset);
if (idType != 0 /* PredefinedTransformName */) warn("file uses unsupported transform identifier type");

Try / catch

try { package = Package.Open(path); }
catch (NotSupportedException)
{
    throw new InvalidDataException("Package stores a transform identifier type unsupported by this runtime.");
}

Prevention

When it happens

Trigger: Reading a compound file whose data space definition block stores a transform identifier type other than the predefined-transform-name type (e.g. a GUID/CLSID-based or class-name-based identifier written by another producer), causing InstantiateDataTransformObject to be called with transformClassType != TransformIdentifierTypes_PredefinedTransformName during file load.

Common situations: Opening a package written by legacy Windows RM/DRM tooling or third-party compound-file writers that used non-predefined transform identifier types; hand-edited or corrupted data space info streams; porting files across WPF/WindowsBase versions where supported identifier types were reduced.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/f32991669d5992ab. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/IO/Packaging/CompoundFile/DataSpaceManager.cs:719

            timeSeed++;
            generatedName = timeSeed.ToString(CultureInfo.InvariantCulture);
        }

        // Submit the definition
        DefineDataSpace( transformStack, generatedName );

        return generatedName;
    }

    /// <summary>
    /// Tranform object is created. We are no longer using reflection to do this. We are supporting limited data transforms.
    /// </summary>
    private IDataTransform InstantiateDataTransformObject(int transformClassType,  string transformClassName, TransformEnvironment transformEnvironment )
    {
        object transformInstance = null;

        if (transformClassType != (int) TransformIdentifierTypes_PredefinedTransformName)
            throw new NotSupportedException(SR.TransformTypeUnsupported);

        // Transform Identifier: we preserve casing, but do case-insensitive comparison
        if (string.Equals(transformClassName, RightsManagementEncryptionTransform.ClassTransformIdentifier, StringComparison.OrdinalIgnoreCase))
        {
            transformInstance = new RightsManagementEncryptionTransform( transformEnvironment);
        }
        else if (string.Equals(transformClassName, CompressionTransform.ClassTransformIdentifier, StringComparison.OrdinalIgnoreCase))
        {
             transformInstance = new CompressionTransform( transformEnvironment );
        }
        else
        {
            //this transform class is not supported. Need to change this to appropriate error.
            throw new ArgumentException(
                    SR.TransformLabelUndefined);
        }

        if (null != transformInstance)

View on GitHub (pinned to 81131a70a4)