quarkusio/quarkus · error · SerializationException

Unexpected index $index

Error message

Unexpected index $index

What it means

ViolationReportViolationSerializer deserializes Violation.Violation entries expecting exactly two elements: index 0 = field, index 1 = message. Any other index reached in the decode loop throws SerializationException("Unexpected index $index").

Source

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

    override val descriptor: SerialDescriptor =
        buildClassSerialDescriptor(
            "io.quarkus.hibernate.validator.runtime.jaxrs.ViolationReport.Violation"
        ) {
            element("field", serialDescriptor<String>())
            element("message", serialDescriptor<String>())
        }

    override fun deserialize(decoder: Decoder): ViolationReport.Violation {
        return decoder.decodeStructure(descriptor) {
            var field: String? = null
            var message: String? = null

            loop@ while (true) {
                when (val index = decodeElementIndex(descriptor)) {
                    CompositeDecoder.DECODE_DONE -> break@loop
                    0 -> field = decodeStringElement(descriptor, 0)
                    1 -> message = decodeStringElement(descriptor, 1)
                    else -> throw SerializationException("Unexpected index $index")
                }
            }

            ViolationReport.Violation(requireNotNull(field), requireNotNull(message))
        }
    }

    override fun serialize(encoder: Encoder, value: ViolationReport.Violation) {
        encoder.encodeStructure(descriptor) {
            encodeStringElement(descriptor, 0, value.field)
            encodeStringElement(descriptor, 1, value.message)
        }
    }
}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Restrict violation JSON entries to only `field` and `message` keys
  2. Use Json { ignoreUnknownKeys = true } for decoding external payloads
  3. Align producer and consumer versions of the violation report schema

Example fix

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

Strategy: try-catch

Validate before calling

val allowed = setOf("field", "message")
require(entry.keys().all { it in allowed }) { "Unknown keys in violation entry" }

Try / catch

try {
    Json.decodeFromString(ViolationReportViolationSerializer, body)
} catch (e: SerializationException) {
    Json { ignoreUnknownKeys = true }.decodeFromString(ViolationReportViolationSerializer, body)
}

Prevention

When it happens

Trigger: Deserializing a violation entry JSON object with more/unknown keys than `field` and `message`, producing element indices beyond 1 in the strict decoder.

Common situations: Bean Validation reports produced by a different Quarkus/RESTEasy version with additional properties; clients sending extended violation objects; strict Json configuration without ignoreUnknownKeys.

Related errors


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