dotnet/aspnetcore · error · RuntimeException
Invalid invocation result kind.
Error message
Invalid invocation result kind.
What it means
createCompletionMessage reads the integer result-kind field of an incoming CompletionMessage and switches on it; the protocol defines only ERROR_RESULT (1), VOID_RESULT (2), and NON_VOID_RESULT (3). Any other value means the message is malformed or produced by an incompatible peer, so the client refuses to interpret it.
Solutions
- Align the SignalR client and server to the same protocol version.
- If you control the sender, ensure resultKind is strictly 1, 2, or 3.
- Treat the occurrence as a connection-fatal protocol violation: tear down and reconnect to a compatible endpoint.
Example fix
// before - server emits an out-of-range result kind // after - server uses the documented constants packer.packInt(/*ERROR_RESULT*/1); // or 2 VOID_RESULT, 3 NON_VOID_RESULT
Defensive patterns
Strategy: validation
Validate before calling
// If you control the sender, assert resultKind is one of the defined constants before sending
int[] VALID = {/*ERROR_RESULT*/1, /*VOID_RESULT*/2, /*NON_VOID_RESULT*/3};
if (!IntStream.of(VALID).anyMatch(k -> k == resultKind)) {
throw new IllegalArgumentException("Bad result kind: " + resultKind);
} Type guard
static boolean isValidResultKind(int k) {
return k == 1 || k == 2 || k == 3;
} Try / catch
try {
protocol.parseMessages(buffer, binder);
} catch (RuntimeException ex) {
if ("Invalid invocation result kind.".equals(ex.getMessage())) {
// protocol violation - reconnect to a compatible server
connection.stop();
}
throw ex;
} Prevention
- Run client and server on the same SignalR MessagePack protocol version.
- Reject non-Microsoft peers that emit non-standard completion frames.
- Treat this as connection-fatal and reconnect.
When it happens
Trigger: The server sends a CompletionMessage whose resultKind is not 1, 2, or 3 (see MessagePackHubProtocol.java:45-47, 249-261). This is a wire/protocol violation, typically from a version mismatch between client and server MessagePack protocol implementations.
Common situations: Upgrading one side of the connection to a newer SignalR protocol that changed the result-kind encoding, corrupted bytes deserializing to an unexpected int, or a non-Microsoft server emitting non-standard completion frames.
Related errors
- Error reading length header.
- Error reading MessagePack data.
- Extension types are not supported
- MessagePack message was length
- Unexpected message type
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/93492921ab3fe9b6.
Report an issue: GitHub.
Appendix: source
Thrown at src/SignalR/clients/java/signalr/messagepack/src/main/java/com/microsoft/signalr/messagepack/MessagePackHubProtocol.java:260
Map<String, String> headers = readHeaders(unpacker);
String invocationId = unpacker.unpackString();
int resultKind = unpacker.unpackInt();
String error = null;
Object result = null;
switch (resultKind) {
case ERROR_RESULT:
error = unpacker.unpackString();
break;
case VOID_RESULT:
break;
case NON_VOID_RESULT:
Type itemType = binder.getReturnType(invocationId);
result = readValue(unpacker, itemType, payload, true);
break;
default:
throw new RuntimeException("Invalid invocation result kind.");
}
return new CompletionMessage(headers, invocationId, result, error);
}
private HubMessage createStreamInvocationMessage(MessageUnpacker unpacker, InvocationBinder binder, int itemCount, ByteBuffer payload) throws IOException {
Map<String, String> headers = readHeaders(unpacker);
String invocationId = unpacker.unpackString();
String target = unpacker.unpackString();
Object[] arguments = null;
try {
List<Type> types = binder.getParameterTypes(target);
arguments = bindArguments(unpacker, types, payload);
} catch (Exception ex) {
return new InvocationBindingFailureMessage(invocationId, target, ex);
}
View on GitHub (pinned to 3600ca084e)