{"record":{"id":"d90091b5807fcd50","repo":"rancher/rancher","slug":"failed-to-convert-token-key-to-hash-w","errorCode":null,"errorMessage":"failed to convert token key to hash: %w","messagePattern":"failed to convert token key to hash: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/auth/tokens/manager.go","lineNumber":679,"sourceCode":"\t\tTTLMillis:     0,\n\t\tDescription:   input.Description,\n\t\tUserID:        input.UserName,\n\t\tAuthProvider:  input.AuthProvider,\n\t\tUserPrincipal: input.UserPrincipal,\n\t\tIsDerived:     true,\n\t\tToken:         key,\n\t\tClusterName:   clusterName,\n\t}\n\tif input.TTL != nil {\n\t\ttoken.TTLMillis = *input.TTL\n\t}\n\tif input.Randomize {\n\t\ttoken.ObjectMeta.Name = \"\"\n\t\ttoken.ObjectMeta.GenerateName = input.TokenName\n\t}\n\terr = ConvertTokenKeyToHash(token)\n\tif err != nil {\n\t\treturn \"\", nil, fmt.Errorf(\"failed to convert token key to hash: %w\", err)\n\t}\n\n\tlogrus.Infof(\"Creating token for user %s\", input.UserName)\n\terr = wait.ExponentialBackoff(backoff, func() (bool, error) {\n\t\t// Backoff was added here because it is possible the token is in the process of deleting.\n\t\t// This should cause the create to retry until the delete is finished.\n\t\tnewToken, err := m.tokens.Create(token)\n\t\tif err != nil {\n\t\t\tif apierrors.IsAlreadyExists(err) {\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t\treturn false, err\n\t\t}\n\t\ttoken = newToken\n\t\treturn true, nil\n\t})\n\tif err != nil {\n\t\treturn \"\", nil, err","sourceCodeStart":661,"sourceCodeEnd":697,"githubUrl":"https://github.com/rancher/rancher/blob/932558d4e68565aff2d2f36e89ec4a391b06e7c5/pkg/auth/tokens/manager.go#L661-L697","documentation":"EnsureClusterToken hashes the generated token key before storing it (ConvertTokenKeyToHash in pkg/auth/tokens/token_util.go). Hashing only runs when the token-hashing feature flag is enabled; the hasher (hashers.GetHasher, bcrypt-backed) can fail on pathological inputs (e.g. keys longer than bcrypt's 72-byte limit) or hasher construction errors. Because the key is server-generated with a fixed format, this error is rare and indicates an environment/feature-flag anomaly rather than user input.","triggerScenarios":"Creating a cluster/kubeconfig token with features.TokenHashing enabled while hasher.CreateHash fails — an oversized key (custom build injecting long keys) or a corrupted hasher configuration.","commonSituations":"Enabling token hashing on a build with a custom hasher; downstream forks generating non-standard key lengths.","solutions":["Check the preceding log line 'Failed to generate hash from token' for the root cause","If you control key generation, keep keys well under 72 bytes","Report upstream if it reproduces with a stock Rancher build and server-generated keys"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Cap custom token keys before they reach the hasher\nconst maxBcryptInput = 72\nif len(token.Token) > maxBcryptInput {\n    return fmt.Errorf(\"token key exceeds %d bytes and cannot be hashed\", maxBcryptInput)\n}","typeGuard":"func hashableTokenKey(key string) bool {\n    return len(key) > 0 && len(key) <= 72\n}","tryCatchPattern":"if _, _, err := mgr.EnsureClusterToken(clusterName, input); err != nil {\n    if strings.Contains(err.Error(), \"failed to convert token key to hash\") {\n        // hashing-stage failure: check token-hashing feature config and key length, do not blind-retry\n        return diagnoseHasherConfig()\n    }\n    return err\n}","preventionTips":["Test the token-hashing feature flag on a staging tier with realistic token volume before enabling broadly","If you fork token generation, assert key length under 72 bytes in unit tests","Correlate with the 'Failed to generate hash from token' log line which carries the root cause"],"tags":["authentication","token-hashing","bcrypt","go"],"backgroundTag":null,"analyzedSha":"932558d4e68565aff2d2f36e89ec4a391b06e7c5","analyzedAt":"2026-08-16T04:37:02.125Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}