Most likely that the code in transit is modified by browser. Try doing UrlEncode on the token:
var code = await userManager.GenerateEmailConfirmationTokenAsync(userId);
code = System.Web.HttpUtility.UrlEncode(code);
Otherwise browser messes with the special symbols that can be present in the token.