temporalio/temporal · error
stream not supported
Error message
stream not supported
What it means
errHTTPGRPCStreamNotSupported is returned by the HTTP API server's NewStream implementation: the Temporal HTTP API is a unary (POST/GET JSON) gateway over gRPC and does not support gRPC streaming. Any attempt to open a gRPC stream through the HTTP gateway fails with this error.
Source
Thrown at service/frontend/http_api_server.go:63
serveMux *runtime.ServeMux
stopped chan struct{}
allowedHosts dynamicconfig.TypedPropertyFn[*regexp.Regexp]
matchAdditionalHeaders map[string]bool
matchAdditionalHeaderPrefixes []string
}
var defaultForwardedHeaders = []string{
"Authorization-Extras",
"X-Forwarded-For",
http.CanonicalHeaderKey(headers.ClientNameHeaderName),
http.CanonicalHeaderKey(headers.ClientVersionHeaderName),
}
type httpRemoteAddrContextKey struct{}
var (
errHTTPGRPCListenerNotTCP = errors.New("must use TCP for gRPC listener to support HTTP API")
errHTTPGRPCStreamNotSupported = errors.New("stream not supported")
)
// NewHTTPAPIServer creates an [HTTPAPIServer].
//
// routes registered with additionalRouteRegistrationFuncs take precedence over the auto generated grpc proxy routes.
func NewHTTPAPIServer(
serviceConfig *Config,
rpcConfig config.RPC,
grpcListener net.Listener,
tlsConfigProvider encryption.TLSConfigProvider,
handler Handler,
operatorHandler *OperatorHandlerImpl,
interceptors []grpc.UnaryServerInterceptor,
metricsHandler metrics.Handler,
router *mux.Router,
namespaceRegistry namespace.Registry,
logger log.Logger,
) (*HTTPAPIServer, error) {View on GitHub (pinned to bde624efd1)
Solutions
- Use streaming RPCs against the native gRPC port (default 7233), not the HTTP API port (default 7243)
- Restructure the call as unary operations (polling) if you must stay on the HTTP API
- Check client configuration so SDK transport selection matches the endpoint type
Example fix
// before: client dials HTTP port for streaming
conn, _ := grpc.Dial("localhost:7243")
// after: use gRPC port
conn, _ := grpc.Dial("localhost:7233") Defensive patterns
Strategy: fallback
Validate before calling
// check the method is unary before routing through the HTTP API
if methodKind(methodDesc) != grpc.UnaryCall {
// route to native gRPC endpoint instead
} Try / catch
if strings.Contains(err.Error(), "stream not supported") { // switch to gRPC port and retry as stream or poll as unary } Prevention
- Point streaming clients at the gRPC port, HTTP clients at the HTTP port
- Treat the HTTP API as unary-only and implement polling instead of streaming
- Verify SDK transport configuration matches endpoint type
When it happens
Trigger: An HTTP client or proxy invoking a streaming RPC method (gRPC server-streaming/bidi) against the HTTP API server, or a generated client attempting NewStream over the HTTP transport.
Common situations: Using grpc-gateway style clients expecting streaming, SDKs pointed at the HTTP port instead of the gRPC port, or workloads requiring long-lived streams (e.g. workflow task streams) misrouted through HTTP.
Related errors
- must use TCP for gRPC listener to support HTTP API
- only comparison and "and" expression is supported
- only comparison and "and" expression is supported
- unknown admin batch type: %T
- not supported batch type: %v
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/7610aedeb1fe027a.
Report an issue: GitHub.