apache/cassandra · error · MarshalException

Error decoding JSON:

Error message

Error decoding JSON: 

What it means

JsonUtils.fromJsonMap deserializes a byte array into a Map using Jackson. If Jackson cannot parse the bytes as JSON (malformed syntax, wrong encoding) it throws IOException, which is wrapped in a MarshalException prefixed with 'Error decoding JSON: '. The original Jackson message is appended, so the detail is in the exception text.

Solutions

  1. Print the full MarshalException message to see the underlying Jackson parse error
  2. Validate the byte payload with a JSON validator before decoding
  3. Confirm the source of the bytes (column value vs user input) and that it was produced by JsonUtils.serializeToJsonString
  4. Check JVM file.encoding/charset consistency; pass UTF-8 encoded bytes

Example fix

// before
Map<String, String> m = JsonUtils.fromJsonMap(rawBytes);
// after
String json = new String(rawBytes, StandardCharsets.UTF_8);
if (!json.trim().startsWith("{")) throw new IllegalArgumentException("Not a JSON object: " + json);
Map<String, String> m = JsonUtils.fromJsonMap(rawBytes);
Defensive patterns

Strategy: try-catch

Validate before calling

// Java
public static Map<String, String> safeFromJsonMap(byte[] bytes) {
    String s = new String(bytes, StandardCharsets.UTF_8).trim();
    if (!s.startsWith("{")) throw new IllegalArgumentException("Not a JSON object: " + s);
    return JsonUtils.fromJsonMap(bytes);
}

Type guard

static boolean isJsonObject(byte[] b) {
    if (b == null || b.length == 0) return false;
    String s = new String(b, StandardCharsets.UTF_8).trim();
    return s.startsWith("{") && s.endsWith("}");
}

Try / catch

try {
    Map<String, String> m = JsonUtils.fromJsonMap(bytes);
} catch (MarshalException e) {
    logger.error("JSON map decode failed: {}", e.getMessage());
    // fall back to default / reject record
}

Prevention

When it happens

Trigger: Calling JsonUtils.fromJsonMap(byte[]) with bytes that are not valid JSON object text: truncated input, non-UTF8 bytes, JSON arrays or scalars when a Map is expected, or corrupt values stored in the database.

Common situations: Decoding a collection-typed column value written by a different application/version; hand-edited CQL literal values; data migrated from another format; reading legacy JSON stored without proper validation.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/utils/JsonUtils.java:161

        try
        {
            return JSON_OBJECT_MAPPER.readValue(json, Map.class);
        }
        catch (IOException ex)
        {
            throw new MarshalException("Error decoding JSON string: " + ex.getMessage());
        }
    }

    public static <T> Map<String, T> fromJsonMap(byte[] bytes)
    {
        try
        {
            return JSON_OBJECT_MAPPER.readValue(bytes, Map.class);
        }
        catch (IOException ex)
        {
            throw new MarshalException("Error decoding JSON: " + ex.getMessage());
        }
    }

    public static List<String> fromJsonList(byte[] bytes)
    {
        try
        {
            return JSON_OBJECT_MAPPER.readValue(bytes, List.class);
        }
        catch (IOException ex)
        {
            throw new MarshalException("Error decoding JSON: " + ex.getMessage());
        }
    }

    public static List<String> fromJsonList(String json)
    {
        try

View on GitHub (pinned to 88fd0f6a0e)