{"record":{"id":"b4fef208d43fe82b","repo":"rancher/rancher","slug":"cannot-decode-uuid-string-s-to-hex-w","errorCode":null,"errorMessage":"cannot decode uuid string '%s' to hex: %w","messagePattern":"cannot decode uuid string '(.+?)' to hex: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/auth/providers/activedirectory/guid/guid.go","lineNumber":85,"sourceCode":"// New returns a GUID object\nfunc New(encoded []byte) (GUID, error) {\n\tif len(encoded) != 16 {\n\t\treturn nil, errors.New(\"cannot create GUID from encoded bytes: invalid length\")\n\t}\n\n\treturn GUID(encoded), nil\n}\n\n// Parse returns a GUID object from a RFC4122 UUID string\nfunc Parse(uuid string) (GUID, error) {\n\tif !uuidRegex.MatchString(uuid) {\n\t\treturn nil, errors.New(\"cannot parse UUID to objectGUID: invalid format\")\n\t}\n\n\tuuid = strings.ReplaceAll(uuid, \"-\", \"\")\n\tuuidBytes, err := hex.DecodeString(uuid)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot decode uuid string '%s' to hex: %w\", uuid, err)\n\t}\n\n\treturn GUID(swap(uuidBytes)), nil\n}\n\n// Escape returns an escaped string format of the objectGUID that can be safely used\n// through the LDAP search. Every byte has to be encoded in an hex string,\n// and prefixed with the '\\' character. If a byte has a hex encoded string of\n// length 1 then it will be prefixed with a '0'.\nfunc Escape(guid GUID) string {\n\tbuilder := strings.Builder{}\n\n\thexArray := hexes(guid.Bytes())\n\tfor _, hex := range hexArray {\n\t\tbuilder.WriteString(`\\`)\n\t\tbuilder.WriteString(hex)\n\t}\n","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/rancher/rancher/blob/932558d4e68565aff2d2f36e89ec4a391b06e7c5/pkg/auth/providers/activedirectory/guid/guid.go#L67-L103","documentation":"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'.","triggerScenarios":"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.","commonSituations":"Essentially never seen in production; the sibling invalid-format error is the one callers actually hit for malformed UUIDs.","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"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"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}$`)\n\nfunc isRFC4122UUID(s string) bool { return uuidRe.MatchString(s) }","tryCatchPattern":"g, err := guid.Parse(uuidStr)\nif err != nil {\n\tif strings.Contains(err.Error(), \"invalid format\") || strings.Contains(err.Error(), \"cannot decode uuid string\") {\n\t\treturn fmt.Errorf(\"%q is not a valid objectGUID UUID\", uuidStr)\n\t}\n\treturn err\n}","preventionTips":["Pre-filter objectGUID strings with a UUID regex before calling Parse","Never share the input string across goroutines between validation and parsing"],"tags":["uuid","guid","activedirectory","go"],"backgroundTag":null,"analyzedSha":"932558d4e68565aff2d2f36e89ec4a391b06e7c5","analyzedAt":"2026-08-16T04:37:02.125Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}