google/ExoPlayer · error · IllegalArgumentException

Unsupported charset: %s

Error message

Unsupported charset: %s

What it means

findNextLineTerminator (backing readSingleLineWithDelimiter and readSingleLine* methods) only supports UTF-8, US-ASCII, UTF-16, UTF-16LE, and UTF-16BE, because line-terminator scanning needs the charset's code-unit stride (1 or 2 bytes). Passing any other java.nio.charset.Charset — UTF-16 with BOM variants handled upstream, but e.g. UTF-32, ISO-8859-1, or a custom charset — throws IllegalArgumentException immediately.

Source

Thrown at library/common/src/main/java/com/google/android/exoplayer2/util/ParsableByteArray.java:639

        return Charsets.UTF_16LE;
      }
    }
    return null;
  }

  /**
   * Returns the index of the next occurrence of '\n' or '\r', or {@link #limit} if none is found.
   */
  private int findNextLineTerminator(Charset charset) {
    int stride;
    if (charset.equals(Charsets.UTF_8) || charset.equals(Charsets.US_ASCII)) {
      stride = 1;
    } else if (charset.equals(Charsets.UTF_16)
        || charset.equals(Charsets.UTF_16LE)
        || charset.equals(Charsets.UTF_16BE)) {
      stride = 2;
    } else {
      throw new IllegalArgumentException("Unsupported charset: " + charset);
    }
    for (int i = position; i < limit - (stride - 1); i += stride) {
      if ((charset.equals(Charsets.UTF_8) || charset.equals(Charsets.US_ASCII))
          && Util.isLinebreak(data[i])) {
        return i;
      } else if ((charset.equals(Charsets.UTF_16) || charset.equals(Charsets.UTF_16BE))
          && data[i] == 0x00
          && Util.isLinebreak(data[i + 1])) {
        return i;
      } else if (charset.equals(Charsets.UTF_16LE)
          && data[i + 1] == 0x00
          && Util.isLinebreak(data[i])) {
        return i;
      }
    }
    return limit;
  }

View on GitHub (pinned to dd430f7053)

Solutions

  1. Map unsupported charsets to a supported equivalent before reading: ISO-8859-1/windows-1252 -> US_ASCII or UTF-8 if bytes allow; UTF-32 -> decode the whole buffer manually with new String(bytes, charset)
  2. Read the line as bytes in a supported charset (UTF-8/US_ASCII) and re-decode the resulting String if you need a different character set afterwards
  3. Pre-validate: keep a Set of Charsets.UTF_8/US_ASCII/UTF_16/UTF_16LE/UTF_16BE and check charset membership before calling readSingleLine*
  4. For genuinely non-UTF encodings, bypass these line helpers and implement your own delimiter scan at byte level

Example fix

// before
Charset cs = Charset.forName(headerCharset); // e.g. iso-8859-1
String line = p.readSingleLine(lineLength, cs); // throws
// after
Charset cs = normalize(headerCharset); // maps latin-1/cp1252 -> US_ASCII when safe, else UTF-8
String line = p.readSingleLine(lineLength, cs);
Defensive patterns

Strategy: type-guard

Validate before calling

private static final Set<Charset> LINE_CHARSETS = Set.of(
    Charsets.UTF_8, Charsets.US_ASCII,
    Charsets.UTF_16, Charsets.UTF_16LE, Charsets.UTF_16BE);
if (!LINE_CHARSETS.contains(charset)) charset = Charsets.UTF_8;

Type guard

static boolean isLineReadableCharset(Charset cs) {
  return cs.equals(Charsets.UTF_8) || cs.equals(Charsets.US_ASCII)
      || cs.equals(Charsets.UTF_16) || cs.equals(Charsets.UTF_16LE)
      || cs.equals(Charsets.UTF_16BE);
}

Try / catch

Not applicable — validate the Charset before calling readSingleLine*; an IllegalArgumentException here is a programming error.

Prevention

When it happens

Trigger: Calling ParsableByteArray.readSingleLine(int length, Charset) or readSingleLineWithDelimiter with Charsets.ISO_8859_1, Charset.forName("UTF-32"), or any non-standard Charset instance. The API accepts any Charset at the type level but only enumerates the five supported constants at runtime.

Common situations: Reading HTTP/ICY/HLS headers that declare charset=iso-8859-1 or windows-1252 in Content-Type and forwarding that Charset into the parser; feeding multi-byte UTF-32 streams; custom Datasources reusing ParsableByteArray for exotic encodings.

Related errors


AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14). Data as JSON: /api/errors/ca919bc4caf82251. Report an issue: GitHub.