English

Developer tools · UUID generator

GUID vs UUID: Microsoft's Braces, Byte Order and Variant Explained

· Background

uuid cryptography browser-apis

Same 16 bytes rendered in RFC order and in GUID structure order, showing which bytes swap
Original ToolAcre vector illustration

GUID is Microsoft's name for a UUID, but the braces, uppercase and byte order can make the same identifier look different across platforms. This post explains each difference and how to compare safely.

The same ID that fails to match across systems — a .NET service and a Java service disagreeing over one record

A .NET service generates a GUID and sends it to a Java service, which attempts to match the value against a UUID from PostgreSQL. The string comparison fails, and systems report that identifiers do not match, even though all three services work with the same underlying 16 bytes. The differences are seemingly cosmetic—braces, casing, byte order—but they cause string comparisons to fail and confuse integration points that do not normalize at the boundary. GUID is Microsoft terminology for what RFC 9562 calls a UUID: a 128-bit identifier with the same bit layout. The two names refer to the same fundamental structure, but the representation differs in ways that catch developers by surprise. Understanding where confusion originates prevents integration bugs.

GUID is a UUID — the shared 128-bit format and where the naming difference came from

GUID stands for Globally Unique Identifier and Globally Unique Identifier and is the name Microsoft uses for what RFC standards call a UUID. The 128-bit layout and version/variant system are identical. RFC 4122 and RFC 9562 specify the UUID format and meaning; Microsoft implements them and uses the term GUID. The naming difference is historical: Microsoft used GUID before UUIDs were standardized by the IETF, and the Microsoft terminology has stuck within the .NET ecosystem. At the bits level, a GUID and a UUID are completely interchangeable. At the formatting level, they differ in presentation: .NET code often writes GUIDs with braces and uppercase letters, while RFC canonical UUIDs use lowercase and no braces.

Braces and uppercase — the registry-style {XXXXXXXX-...} form and how to normalise it

A UUID in canonical RFC form is written as eight, four, four, four, and twelve lowercase hexadecimal characters separated by hyphens: 550e8400-e29b-41d4-a716-446655440000. A .NET GUID is conventionally displayed with braces and uppercase: {550E8400-E29B-41D4-A716-446655440000}. The braces come from Windows Registry format; uppercase is a display convention. Both forms represent the identical 128 bits. To match a GUID from .NET against a UUID from PostgreSQL, strip the braces and normalize the casing, then compare the strings. ToolAcre well-formed check accepts the canonical form and automatically removes braces. Normalization is a minor text transformation that preserves all meaning.

Mixed-endian byte order — how the first three fields are stored little-endian in the GUID structure, and why Guid.ToByteArray differs from RFC byte order

The dangerous difference between GUID and UUID is byte order. RFC 9562 specifies that the first three fields (8, 4, and 4 hexadecimal groups) are stored in big-endian (network) byte order. .NET Guid structure stores the first three fields in little-endian: the bytes are reversed before writing to storage. The same 16 bytes, when written by .NET Guid.ToByteArray() and interpreted by RFC-compliant code, produce completely different text representations. A UUID 550e8400-e29b-41d4-a716-446655440000 in RFC byte order is stored as bytes 55 0e 84 00 e2 9b 41 d4 a7 16 44 66 55 44 00 00.

The legacy Microsoft variant — what a c or d in the fourth group's first character means

In addition to byte order, legacy Microsoft identifiers sometimes use a non-standard variant field. Where RFC 9562 specifies that the first character of the fourth group must be 8, 9, a, or b, legacy Microsoft GUIDs might use c, d, e, or f. These are still valid UUIDs, but they conform to a legacy variant that predates RFC standardization. If you encounter a GUID with c or d in the fourth group first character, you have a valid 128-bit value that does not conform to RFC variant bits. Modern .NET generates RFC-compliant GUIDs, so new identifiers should not exhibit this issue. Legacy variant bits are rare but important to recognize.

Worked example — the same 16 bytes rendered in RFC order and in GUID-structure order, showing exactly which characters swap

Take the UUID 550e8400-e29b-41d4-a716-446655440000 and convert it to .NET GUID byte array form using little-endian convention. In RFC order, the bytes are: first field (550e8400) equals 55 0e 84 00, second field (e29b) equals e2 9b, third field (41d4) equals 41 d4, fourth and fifth equal a7 16 44 66 55 44 00 00. In .NET little-endian: first field becomes 00 84 0e 55, second becomes 9b e2, third becomes d4 41, and the rest remain in big-endian. The full byte array is 00 84 0e 55 9b e2 d4 41 a7 16 44 66 55 44 00 00. If a Java system reads these bytes expecting RFC order, it interprets them as 00840e55-9be2-d441-a716-446655440000.

What this does not cover — SQL Server's NEWSEQUENTIALID and ordering, which are a storage topic of their own

SQL Server NEWSEQUENTIALID function behavior and its specific identifier ordering properties are storage layer and database-specific topics. This post focuses on the format and byte-order differences at the application and serialization level. Deep database-specific UUID handling and byte-order issues are best addressed in documentation specific to that database platform. Different database systems have different approaches and approaches to UUID storage, indexing, sorting, and native support. Some databases detect the version and variant bits automatically, while others require explicit type declarations and byte-order handling at the boundary between systems and storage.

Takeaway: normalise at the boundary — the ToolAcre check accepts the canonical form, which is the shape to standardise on when exchanging IDs

Normalize at the boundary when identifiers cross a .NET/non-.NET system boundary. Strip braces, normalize casing consistently, and byte-swap the first three fields if bytes come from .NET Guid.ToByteArray(). The canonical RFC form is the reference standard: eight, four, four, four, and twelve lowercase hexadecimal characters with hyphens, no braces, big-endian byte order. When exchanging with .NET systems, agree on a normalized form and apply conversions explicitly in integration code. Document byte-order handling and test conversions thoroughly. The core fundamental similarities between GUID and UUID mean most 128 bits are identical.