JamesNK/Newtonsoft.Json · error · ArgumentException
An ObjectId must be 12 bytes
Error message
An ObjectId must be 12 bytes
What it means
Thrown by the BsonObjectId constructor when the supplied byte array is not exactly 12 bytes long. A MongoDB ObjectId is defined as a fixed 12-byte value (4-byte timestamp, 5-byte random, 3-byte counter), so any other length is invalid. This is an ArgumentException from BsonObjectId.cs:54.
Source
Thrown at Src/Newtonsoft.Json/Bson/BsonObjectId.cs:54
[Obsolete("BSON reading and writing has been moved to its own package. See https://www.nuget.org/packages/Newtonsoft.Json.Bson for more details.")]
public class BsonObjectId
{
/// <summary>
/// Gets or sets the value of the Oid.
/// </summary>
/// <value>The value of the Oid.</value>
public byte[] Value { get; }
/// <summary>
/// Initializes a new instance of the <see cref="BsonObjectId"/> class.
/// </summary>
/// <param name="value">The Oid value.</param>
public BsonObjectId(byte[] value)
{
ValidationUtils.ArgumentNotNull(value, nameof(value));
if (value.Length != 12)
{
throw new ArgumentException("An ObjectId must be 12 bytes", nameof(value));
}
Value = value;
}
}
}View on GitHub (pinned to 4f73e74372)
Solutions
- Ensure the byte array passed to the BsonObjectId constructor is exactly 12 bytes.
- If you have a 24-character hex string, convert it with the correct decoder (2 hex chars -> 1 byte = 12 bytes), not Encoding.ASCII.GetBytes.
- If you have a Guid, do not pass it directly; map the relevant 12 bytes explicitly.
- Switch to the dedicated Newtonsoft.Json.Bson package which has its own ObjectId handling.
Example fix
// before: passing a hex string's ASCII bytes (24 bytes)
var oid = new BsonObjectId(Encoding.ASCII.GetBytes("507f1f77bcf86cd799439011"));
// after: decode hex to 12 bytes
byte[] bytes = Enumerable.Range(0, 24)
.Where(i => i % 2 == 0)
.Select(i => Convert.ToByte(hex.Substring(i, 2), 16))
.ToArray();
var oid = new BsonObjectId(bytes); Defensive patterns
Strategy: validation
Validate before calling
byte[] bytes = GetOidBytes();
if (bytes == null || bytes.Length != 12)
throw new ArgumentException($"ObjectId must be 12 bytes, got {bytes?.Length ?? 0}");
var oid = new BsonObjectId(bytes); Type guard
static bool IsValidObjectId(byte[] b) => b != null && b.Length == 12;
Try / catch
try { return new BsonObjectId(bytes); }
catch (ArgumentException ex) when (ex.Message.Contains("12 bytes"))
{
throw new InvalidDataException($"Bad ObjectId length: {bytes?.Length}", ex);
} Prevention
- Always decode 24-char hex strings to exactly 12 bytes before constructing a BsonObjectId.
- Never pass Guid.ToByteArray() (16 bytes) directly as an ObjectId.
- Pre-validate length to give a clearer error than the library's generic message.
When it happens
Trigger: Calling `new BsonObjectId(bytes)` with a byte array whose Length is not 12. Commonly happens when deserializing an OID from a hex string that was converted with the wrong encoding, or when passing a 16-byte Guid or a truncated/padded value.
Common situations: Parsing a 24-char hex string but forgetting to decode it (passing the string's ASCII bytes, 24 bytes). Passing a Guid.ToByteArray() (16 bytes) directly. Reading a corrupt or partial BSON stream whose OID field is not 12 bytes. Using the obsolete in-box BsonObjectId instead of the dedicated BSON package's ObjectId type.
Related errors
- Expected Bytes but got {0}.
- Delimiter must be a single or double quote.
- Constructor name cannot be empty.
- start
- Unexpected token when writing BSON: {0}
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/66edb447978f8ede.
Report an issue: GitHub.