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.

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.

Appendix: 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)