JamesNK/Newtonsoft.Json · error · JsonSerializationException

Unable to serialize instance of '{0}'.

Error message

Unable to serialize instance of '{0}'.

What it means

Thrown at serialization time for types whose FullName is in Json.NET's BlacklistedTypeNames (e.g. System.IO.DirectoryInfo, System.IO.FileInfo). For these types the contract resolver registers an OnSerializing callback (ThrowUnableToSerializeError, line 440) that throws a JsonSerializationException before serialization proceeds. This guard exists because serializing such types without ISerializable support causes a stack overflow (GitHub issue #1541).

Source

Thrown at Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs:442

            MemberInfo? extensionDataMember = GetExtensionDataMemberForType(contract.NonNullableUnderlyingType);
            if (extensionDataMember != null)
            {
                SetExtensionDataDelegates(contract, extensionDataMember);
            }

            // serializing DirectoryInfo without ISerializable will stackoverflow
            // https://github.com/JamesNK/Newtonsoft.Json/issues/1541
            if (Array.IndexOf(BlacklistedTypeNames, objectType.FullName) != -1)
            {
                contract.OnSerializingCallbacks.Add(ThrowUnableToSerializeError);
            }

            return contract;
        }

        private static void ThrowUnableToSerializeError(object o, StreamingContext context)
        {
            throw new JsonSerializationException("Unable to serialize instance of '{0}'.".FormatWith(CultureInfo.InvariantCulture, o.GetType()));
        }

        private MemberInfo? GetExtensionDataMemberForType(Type type)
        {
            IEnumerable<MemberInfo> members = GetClassHierarchyForType(type).SelectMany(baseType =>
            {
                IList<MemberInfo> m = new List<MemberInfo>();
                m.AddRange(baseType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly));
                m.AddRange(baseType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly));

                return m;
            });

            MemberInfo? extensionDataMember = members.LastOrDefault(m =>
            {
                MemberTypes memberType = m.MemberType();
                if (memberType != MemberTypes.Property && memberType != MemberTypes.Field)
                {

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Do not serialize the blacklisted type; project its relevant fields into a plain DTO and serialize that instead.
  2. Add [JsonIgnore] to the DirectoryInfo/FileInfo member so it is excluded from the graph.
  3. Write a custom JsonConverter for the type that emits only the fields you need (e.g. FullName).

Example fix

// before
var json = JsonConvert.SerializeObject(directoryInfo); // throws Unable to serialize

// after
var dto = new { directoryInfo.FullName, directoryInfo.Name };
var json = JsonConvert.SerializeObject(dto);
Defensive patterns

Strategy: validation

Validate before calling

static readonly HashSet<string> Blacklist = new() { "System.IO.DirectoryInfo", "System.IO.FileInfo" };
if (value != null && Blacklist.Contains(value.GetType().FullName))
    throw new InvalidOperationException($"Do not serialize {value.GetType()}; project to a DTO.");
var json = JsonConvert.SerializeObject(value);

Type guard

static bool IsBlacklisted(object? value) =>
    value is System.IO.DirectoryInfo || value is System.IO.FileInfo;

Try / catch

try { json = JsonConvert.SerializeObject(value); }
catch (JsonSerializationException ex) when (ex.Message.StartsWith("Unable to serialize instance"))
{
    // project the object into a DTO and retry
}

Prevention

When it happens

Trigger: JsonConvert.SerializeObject(new DirectoryInfo(...)) or any other blacklisted System type instance. The error fires on the OnSerializing hook the moment serialization begins.

Common situations: Attempting to JSON-serialize filesystem objects, process objects, or other System types that hold unmanaged/native state. Also hit when a DTO transitively contains a DirectoryInfo/FileInfo member that gets pulled into the graph.

Related errors


AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07). Data as JSON: /api/errors/d21fc7cdab58a836. Report an issue: GitHub.