UUID subtype 03 vs 04 in MongoDB - cover art

MongoDB and UUID 13 min read

MongoDB UUID subtype 03 vs 04: legacy C# vs standard RFC byte order

June 17, 2026 · 13 min read

MongoDB’s UUID story is really two stories folded into one database type. Subtype 03 exists for historical compatibility with Microsoft GUID encoding - often called “C# byte order” or mixed-endian layout. Subtype 04 is the cross-platform standard: RFC 4122 order, matching what Java’s UUID.toString(), Python’s uuid.UUID, and most REST APIs emit. If your hex dump changes when you move from a .NET service to a Node service without changing the canonical string, you are almost certainly crossing the 03/04 boundary.

Why MongoDB has two UUID subtypes

Early Windows-centric applications stored GUIDs with permuted endianness in the first three fields. Drivers mirrored that layout so existing .NET apps could round-trip identifiers without rewriting millions of rows. As MongoDB expanded beyond Windows shops, interoperability pain grew: the same GUID string could serialize to different 16-byte arrays depending on codec settings.

Subtype 04 was introduced as the portable answer: one byte order, one expectation for new development. Legacy databases still contain subtype 03 values, and some enterprise .NET code paths continue to write 03 unless explicitly configured otherwise. Knowing which subtype a collection uses is as important as knowing whether IDs are strings or binary.

What actually differs: endianness in the first 12 bytes

RFC 4122 stores time_low, time_mid, and time_hi_and_version in network byte order relative to the canonical string groups. Legacy GUID encoding swaps endianness within those fields while leaving the trailing 8 bytes in the same order many developers expect. The result is that octets 0–7 may appear reversed in hex dumps even though 550e8400-e29b-41d4-a716-446655440000 still displays identically after a correct round-trip through the proper codec.

This is not duplicate data - it is two serializations of one 128-bit integer. Comparisons fail if one service writes subtype 03 and another reads assuming subtype 04 without conversion. Unique indexes will treat the permuted bytes as a different key, which is catastrophic for primary keys.

How C# and .NET drivers fit in

System.Guid has long been the reference point for subtype 03. Older MongoDB .NET drivers mapped Guid to BSON Binary with subtype 03 by default so inserts matched SQL Server linked servers and existing desktop software. Modern drivers expose standards-compliant UUID modes, but upgrading a production cluster requires a migration plan, not only a package bump.

// C#: Guid string is canonical RFC display
var g = Guid.Parse("550e8400-e29b-41d4-a716-446655440000");
// Legacy MongoDB driver may persist subtype 3 bytes
// Configure UUID representation to Standard (subtype 4) for new code

When you integrate .NET microservices with Node or Python services, document the BSON subtype at the API boundary. Integration tests should assert byte-for-byte equality on the wire, not only string equality after deserialization.

Converting between subtype 03 and 04

Conversion is a deterministic permutation of the first 12 bytes (the three UUID time fields), not a random re-encoding. Libraries in most languages implement “GUID bytes to RFC bytes” as a well-tested function. Avoid hand-rolling swaps in application code unless you have golden vectors from both ecosystems.

Batch migrations should update documents in place with a cursor, writing new binary values and verifying a sample with dual-read logic before cutting over consumers. Keep backups and run on a staging copy with production-like document sizes to observe index rebuild time.

Choosing a subtype policy for new projects

Default to subtype 04 for all new collections unless you have a hard dependency on legacy GUID bytes elsewhere in the stack. If you must read subtype 03 from an upstream system, convert at ingress and store 04 internally so every downstream consumer shares one representation.

Publish the policy in your internal API catalog and enforce it in CI with contract tests that fail when BSON subtype drifts. The cost of documenting today is negligible compared to reconciling divergent hex in incident response tomorrow.

When auditing an acquired codebase, grep for Binary constructors and legacy GUID helpers rather than assuming all UUID columns are subtype 04. Acquisition integrations often inherit years of .NET defaults that never surfaced until a new Node reporting service joined the cluster.

Open-source ODMs sometimes expose a global switch for UUID representation; verify it matches your connection string and your DBA runbook. Mismatched settings between web and worker processes in the same repo are a frequent source of split-brain subtype data.

FAQ

Which subtype should new MongoDB apps use?
Subtype 04 (RFC 4122 byte order) unless you are constrained by an existing subtype-03 datastore or .NET component that cannot be migrated yet.
Will mongosh show different strings for 03 and 04?
mongosh displays UUIDs using canonical string form after decoding with the correct subtype. The hex payload differs even when the displayed string matches after proper conversion.
Is subtype 03 deprecated?
It is legacy but still supported for compatibility. New driver defaults favor subtype 04; treat 03 as technical debt to plan away from.
Can both subtypes coexist in one collection?
Technically yes, practically it is dangerous. Queries and indexes will not treat permuted bytes as equal. Normalize to one subtype per field.

Related: Binary UUID explained · Fixing UUID endianness · Java UUID conversion · MongoDB UUID converter tool

Browse all tools