{"record":{"id":"cba66e33706bd0f4","repo":"grpc/grpc-java","slug":"received-an-unexpected-response-from-a-host-at-the-cba66e","errorCode":null,"errorMessage":"Received an unexpected response from a host at the S2A's address.","messagePattern":"Received an unexpected response from a host at the S2A's address\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"s2a/src/main/java/io/grpc/s2a/internal/handshaker/S2AStub.java","lineNumber":126,"sourceCode":"    if (doneWriting && doneReading) {\n      logger.log(Level.INFO, \"Stream to the S2A is closed.\");\n      throw new ConnectionClosedException(\"Stream to the S2A is closed.\");\n    }\n    createWriterIfNull();\n    if (!responses.isEmpty()) {\n      IOException exception = null;\n      try {\n        responses.take().getResultOrThrow();\n      } catch (IOException e) {\n        exception = e;\n      }\n      responses.clear();\n      if (exception != null) {\n        throw new IOException(\n            \"Received an unexpected response from a host at the S2A's address. The S2A might be\"\n                + \" unavailable.\", exception);\n      } else {\n        throw new IOException(\"Received an unexpected response from a host at the S2A's address.\");\n      }\n    }\n    try {\n      writer.onNext(req);\n    } catch (RuntimeException e) {\n      writer.onError(e);\n      responses.add(Result.createWithThrowable(e));\n    }\n    try {\n      return responses.take().getResultOrThrow();\n    } catch (ConnectionClosedException e) {\n      // A ConnectionClosedException is thrown by getResultOrThrow when reader calls its\n      // onCompleted method. The close method is called to also close the writer, and then the\n      // ConnectionClosedException is re-thrown in order to indicate to the caller that send\n      // should not be called again.\n      close();\n      throw e;\n    }","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/s2a/src/main/java/io/grpc/s2a/internal/handshaker/S2AStub.java#L108-L144","documentation":"When S2AStub.send() receives a failed response from the S2A stream without an IOException cause, it throws a plain IOException saying it received an unexpected response from a host at the S2A's address. This variant ( no 'S2A might be unavailable' suffix ) indicates the response failed but the failure type is not I/O related.","triggerScenarios":"Calling S2AStub.send() when responses.take().getResultOrThrow() throws a non-IOException failure, or the taken response is an error result without an IOException — e.g. a status error from the wrong/unexpected gRPC server at the S2A address.","commonSituations":"Something other than the S2A ( e.g. an unrelated gRPC server ) is listening at the configured address; S2A returned an error status on the stream.","solutions":["Confirm the configured S2A address serves the actual S2A handshaker service.","Check S2A process logs for the error it returned on the stream.","Recreate the stub/channel and retry after the stream is reset."],"exampleFix":"// before\n// address points to unrelated service\nchannel = ManagedChannelBuilder.forTarget(\"10.0.0.5:9000\").usePlaintext().build();\n// after\nchannel = ManagedChannelBuilder.forTarget(s2aProcess.socketPath()).build();","handlingStrategy":"validation","validationCode":"// ensure the gRPC channel speaks to the real S2A handshaker service\nif (!channelHealthCheckForS2aService(channel)) {\n  throw new IllegalStateException(\"Endpoint does not serve the S2A handshaker service\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  resp = stub.send(req);\n} catch (IOException e) {\n  if (e.getCause() == null) {\n    // unexpected non-IO failure: suspect wrong endpoint or error status\n    logger.warning(\"Non-IO failure from S2A address: \" + e.getMessage());\n  }\n  throw e;\n}","preventionTips":["Pin the S2A address to the S2A process's socket/port, not a shared endpoint.","Check S2A logs when it returns error statuses on the stream.","Recreate the stub after any stream error."],"tags":["grpc","network","s2a","unexpected-response"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}