How do I represent a UUID in a protobuf message?

Protocol BuffersUuid

Protocol Buffers Problem Overview

I want to attach a UUID to a field in my protobuf User message example.

message User {
  // field containing id as UUID type
  required string email;
  optional string name;

I know that protobuf messages do not yet support the UUID type. I've read that the best approach is to have a UUID message type.

So I'm guessing my User message would import my UUID message proto definition and use it as a field type like so:

import "myproject/UUID.proto";

message User {
  required UUID id;
  required string email;
  optional string name;

My question is, how will the UUID message look like, and how will I encode/decode it? I'm aiming for Java/Scala and C# compatibility.

Protocol Buffers Solutions

Solution 1 - Protocol Buffers

You should probably use string or bytes to represent a UUID. Use string if it is most convenient to keep the UUID in human-readable format (e.g. "de305d54-75b4-431b-adb2-eb6b9e546014") or use bytes if you are storing the 128-bit value raw. (If you aren't sure, you probably want string.)

Wrapping the value in a message type called UUID can be helpful to make the code more self-documenting but will have some performance overhead and isn't strictly required. If you want to do this, define the type like:

message UUID {
  required string value = 1;


message UUID {
  required bytes value = 1;

Solution 2 - Protocol Buffers

If anything, you want to use string to avoid problems with endianness. Note that a UUID and a MS GUID that have the same string representation (and therefore are the same "id") have, however, different byte-stream order (big-endian vs little-endian). If you use bytes in the protocol to communicate between Java using UUID and C# using System.Guid, you could end up with flipped IDs.

Solution 3 - Protocol Buffers

I don't have enough reputation points to make a comment, so I have to write this as an answer.

Use a string, not a byte array unlike what some other commenters are saying. According to MS (, "Don't use a bytes field for Guid values. Problems with endianness (Wikipedia definition) can result in erratic behavior when Protobuf is interacting with other platforms, such as Java."

Solution 4 - Protocol Buffers

I would suggest to use string encoding not byte encoding if you want to ensure straight forward interoperability:

message UUID {
  required string value = 1;

The problem with the bytes encoding is: Different UUID libraries use different encoding/decoding schemes for bytes while they agree how to encode/decode strings.

For example see the C#'s System.guid.toBytesArray returns a mixed-endian format: the first three components are little-endian encoded while the last two are big-endian encoded.

In Java, the Apache Commons Library Uuid.toRawBytes returns the uuid in big-endian encoding:

"String": 35918bc9-196d-40ea-9779-889d79b753f0
"C#"    : C9 8B 91 35 6D 19 EA 40 97 79 88 9D 79 B7 53 F0
"Java"  : 35 91 8B C9 19 6D 40 EA 97 79 88 9D 79 B7 53 F0

As a side note: Python 3's Uuid provides both encodings: bytes for the big-endian encoding and bytes_le for the mixed-endian encoding.


All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEdward MaxedonView Question on Stackoverflow
Solution 1 - Protocol BuffersKenton VardaView Answer on Stackoverflow
Solution 2 - Protocol BuffersThales CarvalhoView Answer on Stackoverflow
Solution 3 - Protocol Bufferssw1337View Answer on Stackoverflow
Solution 4 - Protocol BuffersJE42View Answer on Stackoverflow