{"record":{"id":"4bbd1b0fe73c6de4","repo":"grpc/grpc-java","slug":"cronet-does-not-support-overriding-authority","errorCode":null,"errorMessage":"Cronet does not support overriding authority","messagePattern":"Cronet does not support overriding authority","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"cronet/src/main/java/io/grpc/cronet/CronetClientStream.java","lineNumber":149,"sourceCode":"\n    // Tests expect the \"plain\" deframer behavior, not MigratingDeframer\n    // https://github.com/grpc/grpc-java/issues/7140\n    optimizeForDirectExecutor();\n  }\n\n  @Override\n  protected TransportState transportState() {\n    return state;\n  }\n\n  @Override\n  protected Sink abstractClientStreamSink() {\n    return sink;\n  }\n\n  @Override\n  public void setAuthority(String authority) {\n    throw new UnsupportedOperationException(\"Cronet does not support overriding authority\");\n  }\n\n  /**\n   * Returns a copy of {@code callOptions} with {@code annotation} included as one of the Cronet\n   * annotation objects. When an RPC is made using a {@link CallOptions} instance returned by this\n   * method, the annotation objects will be attached to the underlying Cronet bidirectional stream.\n   * When the stream finishes, the user can retrieve the annotation objects via {@link\n   * org.chromium.net.RequestFinishedInfo.Listener}.\n   *\n   * @param annotation the object to attach to the Cronet stream\n   */\n  static CallOptions withAnnotation(CallOptions callOptions, Object annotation) {\n    Collection<Object> existingAnnotations = callOptions.getOption(CRONET_ANNOTATIONS_KEY);\n    ArrayList<Object> newAnnotations;\n    if (existingAnnotations == null) {\n      newAnnotations = new ArrayList<>();\n    } else {\n      newAnnotations = new ArrayList<>(existingAnnotations);","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/cronet/src/main/java/io/grpc/cronet/CronetClientStream.java#L131-L167","documentation":"CronetClientStream does not allow overriding the authority of an RPC; the authority is fixed by the underlying CronetEngine request URL. Calling setAuthority on such a stream always throws UnsupportedOperationException.","triggerScenarios":"An RPC carries CallOptions with a custom authority override (CallOptions.withAuthority) or internal code (e.g. name resolvers/proxies) attempts to set the authority on a Cronet transport stream.","commonSituations":"Using withAuthority() on CallOptions while forcing the Cronet transport; transparent proxy routing setups that rely on authority overrides.","solutions":["Remove CallOptions.withAuthority(...) from the call options when using Cronet transport.","Configure the correct host/port/URL on the CronetEngine / channel target instead of overriding authority per-call.","Switch to a transport that supports authority override (e.g. Netty or OkHttp) if per-call authority is required."],"exampleFix":"// before\nstub.withCallOptions(CallOptions.DEFAULT.withAuthority(\"proxy.example.com\")).callRpc(req);\n// after\nManagedChannel ch = CronetChannelBuilder.forAddress(\"proxy.example.com\", 443, engine).build();","handlingStrategy":"validation","validationCode":"if (callOptions.getAuthority() != null && isCronetTransport) throw new IllegalArgumentException(\"Cronet transport does not support authority override\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid CallOptions.withAuthority when using Cronet","Set the desired host on the channel target / CronetEngine instead","Document transport-specific CallOptions restrictions"],"tags":["grpc","cronet","authority","unsupported-operation"],"backgroundTag":"unsupported-operation","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"}