JamesNK/Newtonsoft.Json · error · JsonSerializationException
Expected Bytes but got {0}.
Error message
Expected Bytes but got {0}. What it means
Thrown by BsonObjectIdConverter.ReadJson when the JsonReader's current token is not JsonToken.Bytes while deserializing a BsonObjectId. The converter expects a byte array (12 bytes) token; any other token type triggers this JsonSerializationException. The {0} shows the actual token type received.
Source
Thrown at Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs:73
else
{
writer.WriteValue(objectId.Value);
}
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.Bytes)
{
throw new JsonSerializationException("Expected Bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
byte[] value = (byte[])reader.Value;
return new BsonObjectId(value);
}
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(BsonObjectId));
}View on GitHub (pinned to 4f73e74372)
Solutions
- Ensure the token for BsonObjectId properties is JsonToken.Bytes (a 12-byte array).
- If your data is a hex string, add a converter that reads the string and produces a BsonObjectId, instead of using BsonObjectIdConverter.
- Migrate away from the obsolete BsonObjectId type to the dedicated Newtonsoft.Json.Bson package's ObjectId.
Example fix
// before: API sends OID as hex string, converter expects bytes
// { "_id": "507f1f77bcf86cd799439011" }
settings.Converters.Add(new BsonObjectIdConverter());
var obj = JsonConvert.DeserializeObject<Foo>(json, settings); // throws
// after: custom converter that handles hex strings
settings.Converters.Add(new HexStringObjectIdConverter()); Defensive patterns
Strategy: validation
Validate before calling
if (reader.TokenType != JsonToken.Bytes)
throw new JsonSerializationException($"BsonObjectId expects bytes, got {reader.TokenType}"); Type guard
static bool IsBytesToken(JsonReader r) => r.TokenType == JsonToken.Bytes;
Try / catch
try { var oid = serializer.Deserialize<BsonObjectId>(reader); }
catch (JsonSerializationException ex) when (ex.Message.Contains("Expected Bytes"))
{
throw new InvalidDataException("OID field is not a byte array token", ex);
} Prevention
- Ensure OID values are emitted as byte arrays, not hex strings, when using BsonObjectIdConverter.
- For hex-string OIDs, write a dedicated converter instead of reusing BsonObjectIdConverter.
- Migrate to the dedicated Newtonsoft.Json.Bson package's ObjectId type.
When it happens
Trigger: Deserializing JSON where a BsonObjectId-typed property maps to a token that is not a byte array, e.g. a JSON string, integer, or object. Because BsonObjectIdConverter is specific to the obsolete BSON support, this typically happens when JSON produced outside the BSON pipeline (e.g. plain JSON with a string OID) is read by a serializer configured with this converter.
Common situations: Mixing plain-JSON data with the BSON-specific BsonObjectIdConverter. Receiving an OID as a 24-char hex string from an API but the converter expects raw bytes. Legacy code still referencing the obsolete BsonObjectId/BsonObjectIdConverter after migrating the wire format to JSON.
Related errors
- Converter cannot read JSON with the specified existing value
- An ObjectId must be 12 bytes
- Unexpected BsonType value: {0}
- Unable to read beyond the end of the stream.
- Unexpected value type when writing binary: {0}
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/e0a62301f18656ed.
Report an issue: GitHub.