egametang/ET · error · ArgumentException

The binary key cannot have an odd number of digits: {0}

Error message

The binary key cannot have an odd number of digits: {0}

What it means

StringHelper.HexToBytes parses a hex string two characters at a time into bytes. An odd number of characters means the string is not valid hex (each byte needs two digits), so it throws ArgumentException listing the offending input.

Source

Thrown at Packages/cn.etetet.core/Scripts/Core/Share/Helper/StringHelper.cs:42

		}

		public static byte[] ToByteArray(this string str)
		{
			byte[] byteArray = Encoding.Default.GetBytes(str);
			return byteArray;
		}

	    public static byte[] ToUtf8(this string str)
	    {
            byte[] byteArray = Encoding.UTF8.GetBytes(str);
            return byteArray;
        }

		public static byte[] HexToBytes(this string hexString)
		{
			if (hexString.Length % 2 != 0)
			{
				throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString));
			}

			var hexAsBytes = new byte[hexString.Length / 2];
			for (int index = 0; index < hexAsBytes.Length; index++)
			{
				string byteValue = "";
				byteValue += hexString[index * 2];
				byteValue += hexString[index * 2 + 1];
				hexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
			}
			return hexAsBytes;
		}

		public static string Fmt(this string text, params object[] args)
		{
			return string.Format(text, args);
		}

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Validate hexString.Length is even before calling HexToBytes.
  2. Re-derive the key from its source and copy the full string.
  3. Left-pad a single-nibble value with a leading '0' if you dropped one.

Example fix

// before
byte[] key = token.HexToBytes();
// after
if (string.IsNullOrEmpty(token) || token.Length % 2 != 0 || !token.All(c => "0123456789abcdefABCDEF".Contains(c)))
    throw new ArgumentException("invalid hex token", nameof(token));
byte[] key = token.HexToBytes();
Defensive patterns

Strategy: validation

Validate before calling

static bool IsHex(string s) => s.Length % 2 == 0 && s.All(c => (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
if (!IsHex(hex)) throw new ArgumentException("not valid hex", nameof(hex));
byte[] b = hex.HexToBytes();

Type guard

public static bool IsValidHexString(string s) => !string.IsNullOrEmpty(s) && s.Length % 2 == 0 && s.All(c => "0123456789abcdefABCDEF".IndexOf(c) >= 0);

Try / catch

try { return hex.HexToBytes(); }
catch (ArgumentException) { throw new ArgumentException("malformed hex key in config", nameof(hex)); }

Prevention

When it happens

Trigger: Passing a hex key/hash string with an odd length, e.g. a truncated MD5/AES key, a leading zero dropped, or a copy-paste that lost a character.

Common situations: Mis-typed secret/hex token in config, key generated by a tool that strips leading zeros, or binary data rendered as hex without zero-padding.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/e21ec17327715788. Report an issue: GitHub.