apache/cassandra · error · InvalidTypeException

%s is not a valid ASCII String

Error message

%s is not a valid ASCII String

What it means

AsciiCodec.serialize() validates that the Java String only contains ASCII characters (matched against ASCII_PATTERN) before encoding it to bytes for the wire. CQL's ascii type only permits 7-bit ASCII, so any non-ASCII character (accents, emoji, CJK, smart quotes) makes the value unrepresentable and the codec throws rather than silently corrupting data.

Source

Thrown at src/java/org/apache/cassandra/cql3/functions/types/TypeCodec.java:1040

     */
    private static class AsciiCodec extends StringCodec
    {

        private static final AsciiCodec instance = new AsciiCodec();

        private static final Pattern ASCII_PATTERN = Pattern.compile("^\\p{ASCII}*$");

        private AsciiCodec()
        {
            super(DataType.ascii(), Charset.forName("US-ASCII"));
        }

        @Override
        public ByteBuffer serialize(String value, ProtocolVersion protocolVersion)
        {
            if (value != null && !ASCII_PATTERN.matcher(value).matches())
            {
                throw new InvalidTypeException(String.format("%s is not a valid ASCII String", value));
            }
            return super.serialize(value, protocolVersion);
        }

        @Override
        public String format(String value)
        {
            if (value != null && !ASCII_PATTERN.matcher(value).matches())
            {
                throw new InvalidTypeException(String.format("%s is not a valid ASCII String", value));
            }
            return super.format(value);
        }
    }

    /**
     * Base class for codecs handling CQL 8-byte integer types such as {@link DataType#bigint()},
     * {@link DataType#counter()} or {@link DataType#time()}.

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Change the column type from ascii to text: ALTER TABLE t ALTER c TYPE text;
  2. Strip or transliterate non-ASCII characters before serializing (e.g. value.replaceAll("[^\\x00-\\x7F]", "")).
  3. Normalize the input (NFKD) and drop combining marks if transliteration is acceptable.
  4. If corruption is expected upstream, validate input at the application boundary before it reaches the driver.

Example fix

// before
String v = "café";
asciiCodec.serialize(v, protocolVersion); // throws
// after
String v = "café".replaceAll("[^\\x00-\\x7F]", ""); // "caf"
asciiCodec.serialize(v, protocolVersion);
Defensive patterns

Strategy: validation

Validate before calling

static final Pattern ASCII = Pattern.compile("^[\\x00-\\x7F]*$");
static void requireAscii(String v) {
    if (v != null && !ASCII.matcher(v).matches())
        throw new IllegalArgumentException("Not ASCII: " + v);
}

Type guard

boolean isAscii(String v) {
    return v == null || v.chars().allMatch(c -> c < 128);
}

Try / catch

try {
    bb = asciiCodec.serialize(value, protocolVersion);
} catch (InvalidTypeException e) {
    bb = asciiCodec.serialize(value.replaceAll("[^\\x00-\\x7F]", ""), protocolVersion);
}

Prevention

When it happens

Trigger: Calling asciiCodec.serialize(value, protocolVersion), or binding a Java String to an ascii column via a prepared statement, when value contains any code point > 0x7F.

Common situations: User-entered text with accents or non-Latin scripts stored into an ascii column; data copied from UTF-8 sources (e.g. Windows-1252 curly quotes, em dashes); schema defined as ascii by mistake when text was intended.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/d1c309a71d61f242. Report an issue: GitHub.