diff --git a/connector/ldap/tweak.go b/connector/ldap/tweak.go
index 34facee761c4db427e32fdcb85682fccb447f0bf..0a97e7652d9fd5a6aaa34461a279d778bfc1ac78 100644
--- a/connector/ldap/tweak.go
+++ b/connector/ldap/tweak.go
@@ -1,6 +1,7 @@
 package ldap
 
 import (
+	"encoding/hex"
 	"strings"
 
 	"github.com/dexidp/dex/connector"
@@ -9,10 +10,18 @@ import (
 // TweakIdentity adjusts attributes received from the LDAP directory. Don't ask
 // why this is necessary. Just learn to accept it.
 func tweakIdentity(id connector.Identity) connector.Identity {
+	id.UserID = tweakUserID(id)
 	id.Username = tweakName(id)
 	return id
 }
 
+func tweakUserID(id connector.Identity) string {
+	// If the UserID happens to be something that is not valid UTF8 (like
+	// Windows/AD SIDs), it gets mangled during JSON marshaling when saved to
+	// storage. Ensure it is UTF8.
+	return hex.EncodeToString([]byte(id.UserID))
+}
+
 func tweakName(id connector.Identity) string {
 	name := id.Username
 	if name == " " {