quarkusio/quarkus · error · SerializationException

Unexpected index $index

Error message

Unexpected index $index

What it means

ViolationReportSerializer is a kotlinx.serialization KSerializer for the RESTClassic/Reactive ViolationReport. Its decodeStructure loop only accepts element indices 0 (title), 1 (status), 2 (violations); any other index from decodeElementIndex throws SerializationException("Unexpected index $index"). This guards against malformed or unknown JSON fields when the decoder is not lenient.

Source

Thrown at extensions/resteasy-reactive/rest-kotlin-serialization/runtime/src/main/kotlin/io/quarkus/resteasy/reactive/kotlin/serialization/runtime/ViolationReportSerializer.kt:48

    override fun deserialize(decoder: Decoder): ViolationReport {
        return decoder.decodeStructure(descriptor) {
            var title: String? = null
            var status: Int? = null
            var violations: List<ViolationReport.Violation> = emptyList()

            loop@ while (true) {
                when (val index = decodeElementIndex(descriptor)) {
                    DECODE_DONE -> break@loop
                    0 -> title = decodeStringElement(descriptor, 0)
                    1 -> status = decodeIntElement(descriptor, 1)
                    2 ->
                        violations =
                            decodeSerializableElement(
                                descriptor,
                                2,
                                ListSerializer(ViolationReportViolationSerializer),
                            )
                    else -> throw SerializationException("Unexpected index $index")
                }
            }

            ViolationReport(
                requireNotNull(title),
                status?.let { Response.Status.fromStatusCode(it) },
                violations,
            )
        }
    }

    override fun serialize(encoder: Encoder, value: ViolationReport) {
        encoder.encodeStructure(descriptor) {
            encodeStringElement(descriptor, 0, value.title)
            encodeIntElement(descriptor, 1, value.status)
            encodeSerializableElement(
                descriptor,
                2,

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure the JSON payload only contains title, status, and violations keys
  2. Configure kotlinx.serialization Json with ignoreUnknownKeys = true when decoding untrusted payloads
  3. Regenerate/align the payload with the server's ViolationReport format (check Quarkus version for format changes)
  4. Write a custom serializer allowing unknown keys if the format must evolve

Example fix

// before
val json = Json
// after
val json = Json { ignoreUnknownKeys = true }
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate payload keys before deserialization
val allowed = setOf("title", "status", "violations")
require(jsonObject.keys().all { it in allowed }) { "Unknown keys in ViolationReport JSON" }

Try / catch

try {
    Json.decodeFromString(ViolationReportSerializer, body)
} catch (e: SerializationException) {
    // retry decode with Json { ignoreUnknownKeys = true }
    Json { ignoreUnknownKeys = true }.decodeFromString(ViolationReportSerializer, body)
}

Prevention

When it happens

Trigger: Deserializing a JSON body into ViolationReport that produces an element index outside 0..2 — typically caused by extra/unknown keys with a strict descriptor or a mismatched JSON shape.

Common situations: Clients posting constraint-violation reports with extra fields; version mismatch between producer and consumer of the violation report format; custom JSON with unexpected ordering/keys under non-ignoring JSON configuration.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/0a0077cd47125b39. Report an issue: GitHub.