{"record":{"id":"7bf892b51d365f71","repo":"sgl-project/sglang","slug":"grpcs-is-not-supported-use-grpc","errorCode":null,"errorMessage":"grpcs:// is not supported; use grpc://","messagePattern":"grpcs:// is not supported; use grpc://","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/disaggregation/encoder/receiver.py","lineNumber":347,"sourceCode":"            self._server.run()\n        except Exception as e:\n            logger.error(f\"EncoderBootstrapServer error: {e}\", exc_info=True)\n\n    def close(self):\n        if self._server is not None:\n            # uvicorn polls should_exit on its own event loop; thread-safe.\n            self._server.should_exit = True\n            logger.info(\"Stopping EncoderBootstrapServer...\")\n        if self.thread.is_alive():\n            self.thread.join(timeout=5)\n            logger.info(\"EncoderBootstrapServer thread stopped\")\n\n\ndef _grpc_target(url: str) -> str:\n    if url.startswith(\"grpc://\"):\n        return url[len(\"grpc://\") :]\n    if url.startswith(\"grpcs://\"):\n        raise ValueError(\"grpcs:// is not supported; use grpc://\")\n    return url\n\n\ndef _normalize_embedding_ports(embedding_port):\n    if embedding_port is None:\n        return []\n    if isinstance(embedding_port, list):\n        return embedding_port\n    return [embedding_port]\n\n\ndef _grpc_scheduler_receive_url(target, req_id, receive_url, receive_count):\n    import grpc\n    from smg_grpc_proto import sglang_encoder_pb2, sglang_encoder_pb2_grpc\n\n    timeout_secs = envs.SGLANG_ENCODER_GRPC_TIMEOUT_SECS.get()\n    channel = grpc.insecure_channel(target)\n    stub = sglang_encoder_pb2_grpc.SglangEncoderStub(channel)","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/disaggregation/encoder/receiver.py#L329-L365","documentation":"Raised by _grpc_target when an encoder URL uses the grpcs:// (TLS) scheme. The gRPC encoder client in SGLang's disaggregated encoder path only supports plaintext grpc:// targets; TLS-secured gRPC connections are not implemented, so the URL is rejected rather than silently downgraded.","triggerScenarios":"Configuring encode_urls / encoder URLs like grpcs://encoder:9000 and invoking send_embedding_port or encode, which call _grpc_target to normalize the URL before creating the gRPC channel.","commonSituations":"Deployments that copy a TLS-enabled gRPC endpoint (common in service meshes or cloud-hosted encoders) into SGLang encoder config; mixing up HTTPS-style URLs with the gRPC scheme.","solutions":["Change grpcs://host:port to grpc://host:port in encoder URL configuration.","If TLS is required, terminate TLS at a sidecar/proxy (e.g. Envoy, nginx, or stunnel) and point SGLang at the plaintext grpc:// proxy address.","Ensure the encoder service itself is listening on plaintext gRPC on that port."],"exampleFix":"# before\n--encoder-urls grpcs://encoder0:9000\n# after\n--encoder-urls grpc://encoder0:9000  # terminate TLS in a proxy if needed","handlingStrategy":"validation","validationCode":"def validate_encoder_url(url: str) -> str:\n    if url.startswith(\"grpcs://\"):\n        raise ValueError(f\"{url}: TLS gRPC unsupported; use grpc:// (terminate TLS at a proxy)\")\n    return url\n\nurls = [validate_encoder_url(u) for u in urls]","typeGuard":null,"tryCatchPattern":"try:\n    target = _grpc_target(url)\nexcept ValueError as e:\n    logger.error(\"encoder URL rejected: %s\", e)\n    target = url.removeprefix(\"grpcs://\")  # only if backend truly is plaintext behind a TLS proxy","preventionTips":["Standardize encoder URL config on grpc:// scheme in templates and helm charts.","Terminate TLS for gRPC encoders at a sidecar (Envoy/stunnel) rather than using grpcs://.","Validate all encoder URLs at startup, not per request."],"tags":["grpc","url-scheme","tls","network","configuration"],"backgroundTag":"unsupported-url-scheme","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}