BeyondDimension/SteamTools · warning · ApplicationException

Invalid serial for Battle.net Authenticator

Error message

Invalid serial for Battle.net Authenticator

What it means

Thrown when a Battle.net serial fails the format regex ^[A-Z]{2}-?[\d]{4}-?[\d]{4}-?[\d]{4}$ (after uppercasing). The serial must be two letters followed by three groups of four digits, with optional dashes; anything else is treated as invalid.

Source

Thrown at src/BD.WTTS.Client.Plugins.Authenticator/UI/ViewModels/AuthenticatorImportPageViewModel.cs:317

                {
                    throw new ApplicationException("HOTP authenticator should have a counter");
                }

                AuthenticatorDTO authenticatorDto = new();

                AuthenticatorValueDTO auth;
                if (string.Compare(issuer, "BattleNet", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    string? serial = query["serial"];
                    if (string.IsNullOrEmpty(serial))
                    {
                        throw new ApplicationException("Battle.net Authenticator does not have a serial");
                    }

                    serial = serial.ToUpper();
                    if (Regex.IsMatch(serial, @"^[A-Z]{2}-?[\d]{4}-?[\d]{4}-?[\d]{4}$") == false)
                    {
                        throw new ApplicationException("Invalid serial for Battle.net Authenticator");
                    }

                    auth = new BattleNetAuthenticator();
                    //char[] decoded = Base32.getInstance().Decode(secret).Select(c => Convert.ToChar(c)).ToArray(); // this is hex string values
                    //string hex = new string(decoded);
                    //((BattleNetAuthenticator)auth).SecretKey = Authenticator.StringToByteArray(hex);

                    ((BattleNetAuthenticator)auth).SecretKey = Base32.GetInstance().Decode(secret);

                    ((BattleNetAuthenticator)auth).Serial = serial;

                    issuer = string.Empty;
                }
                else if (string.Compare(issuer, "Steam", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    auth = new SteamAuthenticator();
                    ((SteamAuthenticator)auth).SecretKey = Base32.GetInstance().Decode(secret);
                    ((SteamAuthenticator)auth).Serial = string.Empty;

View on GitHub (pinned to c16ffa08e0)

Solutions

  1. Re-copy the serial exactly as shown in the Battle.net authenticator (US-XX-XXXX-XXXX-XXXX style).
  2. Strip spaces and ensure only letters/digits/dashes remain before validating.
  3. If the genuine serial uses a different format, extend the regex rather than forcing the value.
  4. Show the expected format in the UI error so the user can self-correct.

Example fix

// before
serial = serial.ToUpper();
if (Regex.IsMatch(serial, @"^[A-Z]{2}-?[\d]{4}-?[\d]{4}-?[\d]{4}$") == false)
    throw new ApplicationException("Invalid serial for Battle.net Authenticator");

// after: normalise dashes/spaces, then a clearer message
serial = serial.ToUpper().Replace(" ", "");
if (!Regex.IsMatch(serial, @"^[A-Z]{2}-?\d{4}-?\d{4}-?\d{4}$"))
    throw new ArgumentException(string.Format(Strings.Import_BadBattleNetSerial, serial));
Defensive patterns

Strategy: validation

Validate before calling

static readonly Regex BattleNetSerial =
    new(@"^[A-Z]{2}-?\d{4}-?\d{4}-?\d{4}$", RegexOptions.Compiled);

bool IsValidBattleNetSerial(string? serial)
    => !string.IsNullOrWhiteSpace(serial) && BattleNetSerial.IsMatch(serial.Trim().ToUpperInvariant());

if (issuer.Equals("BattleNet", StringComparison.OrdinalIgnoreCase) && !IsValidBattleNetSerial(query["serial"]))
    errors.Add(($"Line {n}: serial format invalid (expected US-XXXX-XXXX-XXXX).", line));

Type guard

bool IsValidSerial(string? s) => !string.IsNullOrWhiteSpace(s) && Regex.IsMatch(s.Trim().ToUpperInvariant(), @"^[A-Z]{2}-?\d{4}-?\d{4}-?\d{4}$");

Try / catch

try { ParseAuthenticator(line); }
catch (ApplicationException ex) when (ex.Message == "Invalid serial for Battle.net Authenticator")
{
    importErrors.Add(($"Bad Battle.net serial format (line {n}). Expected US-XXXX-XXXX-XXXX.", line));
    continue;
}

Prevention

When it happens

Trigger: Importing a BattleNet entry whose serial, after ToUpper, does not match the expected two-letters + 12-digits pattern (dashes optional).

Common situations: Serial mistyped or truncated; serial copied with extra characters/spaces; serial from a different/legacy format; regional serial format that doesn't fit the pattern.

Understand the failure class

Related errors


AI-assisted analysis of BeyondDimension/SteamTools@c16ffa08e0 (2026-08-13). Data as JSON: /api/errors/e60099529b6a9161. Report an issue: GitHub.