rancher/rancher · warning
cannot decode uuid string '%s' to hex: %w
Error message
cannot decode uuid string '%s' to hex: %w
What it means
Defensive branch in guid.Parse (pkg/auth/providers/activedirectory/guid/guid.go:85): after uuidRegex already validated the 8-4-4-4-12 hex-and-dash shape, hex.DecodeString on the dash-stripped string still failed. Because the regex admits only ASCII hex digits, decode cannot realistically fail on regex-passing input; malformed input instead fails earlier with 'cannot parse UUID to objectGUID: invalid format'.
Source
Thrown at pkg/auth/providers/activedirectory/guid/guid.go:85
// New returns a GUID object
func New(encoded []byte) (GUID, error) {
if len(encoded) != 16 {
return nil, errors.New("cannot create GUID from encoded bytes: invalid length")
}
return GUID(encoded), nil
}
// Parse returns a GUID object from a RFC4122 UUID string
func Parse(uuid string) (GUID, error) {
if !uuidRegex.MatchString(uuid) {
return nil, errors.New("cannot parse UUID to objectGUID: invalid format")
}
uuid = strings.ReplaceAll(uuid, "-", "")
uuidBytes, err := hex.DecodeString(uuid)
if err != nil {
return nil, fmt.Errorf("cannot decode uuid string '%s' to hex: %w", uuid, err)
}
return GUID(swap(uuidBytes)), nil
}
// Escape returns an escaped string format of the objectGUID that can be safely used
// through the LDAP search. Every byte has to be encoded in an hex string,
// and prefixed with the '\' character. If a byte has a hex encoded string of
// length 1 then it will be prefixed with a '0'.
func Escape(guid GUID) string {
builder := strings.Builder{}
hexArray := hexes(guid.Bytes())
for _, hex := range hexArray {
builder.WriteString(`\`)
builder.WriteString(hex)
}
View on GitHub (pinned to 932558d4e6)
Solutions
- Validate and normalize the UUID string before calling guid.Parse
- If it ever fires, log the exact string: it indicates concurrent mutation or a modified regex
- Handle the invalid-format error for user-input validation; treat this one as an internal invariant violation
Defensive patterns
Strategy: type-guard
Type guard
var uuidRe = regexp.MustCompile(`(?i)^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`)
func isRFC4122UUID(s string) bool { return uuidRe.MatchString(s) } Try / catch
g, err := guid.Parse(uuidStr)
if err != nil {
if strings.Contains(err.Error(), "invalid format") || strings.Contains(err.Error(), "cannot decode uuid string") {
return fmt.Errorf("%q is not a valid objectGUID UUID", uuidStr)
}
return err
} Prevention
- Pre-filter objectGUID strings with a UUID regex before calling Parse
- Never share the input string across goroutines between validation and parsing
When it happens
Trigger: The input string is mutated between the regex check and the decode (shared buffer across goroutines); a fork widened the regex to admit non-hex characters. In the shipped code the branch is effectively unreachable.
Common situations: Essentially never seen in production; the sibling invalid-format error is the one callers actually hit for malformed UUIDs.
Related errors
- no identities can be retrieved
- more than one result found
- regionId can not be empty
- received empty response
- invalid value for maxResults query param
AI-assisted analysis of rancher/rancher@932558d4e6 (2026-08-16).
Data as JSON: /api/errors/b4fef208d43fe82b.
Report an issue: GitHub.