Description
StreamOp.fetchExistingTotalDocs in the compatibility verifier crashes with a NullPointerException when the broker response includes exceptions.
Root Cause
The exceptions field in the broker query response is a JSON array (e.g., [{"errorCode": 410, "message": "..."}]), but the code calls exceptions.get("errorCode") as if it were a JSON object. When Jackson's ArrayNode.get(String) is called, it always returns null, causing the subsequent errorCode.asInt() to throw an NPE.
Steps to Reproduce
- Run the compatibility verifier while a table's segments are still loading (rolling upgrade scenario)
- The broker returns an error response with a non-empty
exceptions array
fetchExistingTotalDocs hits the exceptions-handling path and crashes
Expected Behavior
The method should:
- Correctly index into the exceptions array (e.g.,
exceptions.get(0).get("errorCode"))
- Handle null defensively
- Treat
BROKER_SEGMENT_UNAVAILABLE (305) as a transient condition (same as BROKER_INSTANCE_MISSING) and retry
Affected Component
pinot-compatibility-verifier/src/main/java/org/apache/pinot/compat/StreamOp.java
Description
StreamOp.fetchExistingTotalDocsin the compatibility verifier crashes with aNullPointerExceptionwhen the broker response includes exceptions.Root Cause
The
exceptionsfield in the broker query response is a JSON array (e.g.,[{"errorCode": 410, "message": "..."}]), but the code callsexceptions.get("errorCode")as if it were a JSON object. When Jackson'sArrayNode.get(String)is called, it always returnsnull, causing the subsequenterrorCode.asInt()to throw an NPE.Steps to Reproduce
exceptionsarrayfetchExistingTotalDocshits the exceptions-handling path and crashesExpected Behavior
The method should:
exceptions.get(0).get("errorCode"))BROKER_SEGMENT_UNAVAILABLE(305) as a transient condition (same asBROKER_INSTANCE_MISSING) and retryAffected Component
pinot-compatibility-verifier/src/main/java/org/apache/pinot/compat/StreamOp.java