dromara/Sa-Token · error · IllegalArgumentException

编码字符串长度无效

Error message

编码字符串长度无效

What it means

Thrown by SaSerializerForBase64UseCustomCharacters.stringToBytes when the input string's length is not a multiple of 4 (IllegalArgumentException, no specific code). This custom-alphabet Base64 decoder processes 4-character groups into 3 bytes, so any string whose length % 4 != 0 cannot be a valid encoding from this serializer.

Source

Thrown at sa-token-plugin/sa-token-serializer-features/src/main/java/cn/dev33/satoken/serializer/SaSerializerForBase64UseCustomCharacters.java:102

		}

		return encoded.toString();
	}

	@Override
	public byte[] stringToBytes(String encodedStr) {
		if (CUSTOM_CHARS.length() != 64) {
			throw new IllegalStateException("自定义字符集长度必须为64");
		}

		Map<Character, Integer> charMap = new HashMap<>();
		for (int i = 0; i < CUSTOM_CHARS.length(); i++) {
			charMap.put(CUSTOM_CHARS.charAt(i), i);
		}

		int length = encodedStr.length();
		if (length % 4 != 0) {
			throw new IllegalArgumentException("编码字符串长度无效");
		}

		// 计算填充符数量
		int paddingCount = 0;
		for (int i = length - 1; i >= 0 && encodedStr.charAt(i) == PAD_CHAR; i--) {
			paddingCount++;
		}

		int numGroups = length / 4;
		byte[] decoded = new byte[numGroups * 3 - paddingCount];
		int decodedIndex = 0;

		for (int group = 0; group < numGroups; group++) {
			int[] indices = new int[4];
			for (int j = 0; j < 4; j++) {
				char c = encodedStr.charAt(group * 4 + j);
				if (c == PAD_CHAR) {
					indices[j] = 0; // 填充符处理为0,后续根据paddingCount调整

View on GitHub (pinned to ac2c7f6e94)

Solutions

  1. Regenerate/re-serialize the data with the same custom-characters serializer configuration so encode and decode match
  2. Ensure the serialized string is transmitted intact: URL-encode it, avoid truncation, trim surrounding whitespace
  3. Keep the serializer configuration identical across all services that share the data (set it globally via SaManager.setSaSerializer)

Example fix

// before (services disagree on serializer)
// service A: SaManager.setSaSerializer(new SaSerializerForJackson())
// service B: SaManager.setSaSerializer(new SaSerializerForBase64UseCustomCharacters(...))
// after: configure the same serializer instance type on every service
Defensive patterns

Strategy: validation

Validate before calling

String s = encodedStr == null ? "" : encodedStr;
if (s.length() % 4 != 0) throw new IllegalArgumentException("not a valid encoding from this serializer (length % 4 != 0)");

Try / catch

try { byte[] data = serializer.stringToBytes(input); } catch (IllegalArgumentException e) { log.warn("corrupted serialized value"); recoverFromSource(); }

Prevention

When it happens

Trigger: Calling valueToString/String-to-bytes deserialization on a token or serialized string that was truncated, corrupted, or produced by a different Base64 variant/standard alphabet while the custom-characters serializer is configured.

Common situations: Tokens serialized with the default serializer (or standard Base64) then deserialized after switching the serializer to the custom-characters variant; strings mangled by transport (truncated by URL length limits, header stripping); whitespace/newline accidentally prepended.

Related errors


AI-assisted analysis of dromara/Sa-Token@ac2c7f6e94 (2026-08-14). Data as JSON: /api/errors/2ba54e24c79ae0a9. Report an issue: GitHub.