grafana/k6 · error
failed to create a new stream: %w
Error message
failed to create a new stream: %w
What it means
Thrown by k6's gRPC streaming API when client.newStream(method, params) cannot establish the underlying gRPC stream. beginStream (internal/js/modules/k6/grpc/stream.go:99-102) calls conn.NewStream with the VU context (wrapped in a context.WithTimeout if a params.timeout was given) and wraps any failure with %w, so the tail of the message carries the real grpc-go cause (connection refused, TLS handshake error, unavailable, deadline exceeded, etc.).
Source
Thrown at internal/js/modules/k6/grpc/stream.go:101
Method: s.method,
MethodDescriptor: s.methodDescriptor,
DiscardResponseMessage: p.DiscardResponseMessage,
TagsAndMeta: &p.TagsAndMeta,
Metadata: p.Metadata,
}
ctx := s.vu.Context()
var cancel context.CancelFunc
if p.Timeout != time.Duration(0) {
ctx, cancel = context.WithTimeout(ctx, p.Timeout)
}
s.timeoutCancel = cancel
stream, err := s.client.conn.NewStream(ctx, *req)
if err != nil {
return fmt.Errorf("failed to create a new stream: %w", err)
}
s.stream = stream
metrics.PushIfNotDone(s.vu.Context(), s.vu.State().Samples, metrics.Sample{
TimeSeries: metrics.TimeSeries{
Metric: s.instanceMetrics.Streams,
Tags: s.tagsAndMeta.Tags,
},
Time: time.Now(),
Metadata: s.tagsAndMeta.Metadata,
Value: 1,
})
go s.loop()
return nil
}
func (s *stream) loop() {View on GitHub (pinned to 93accf6570)
Solutions
- Read the wrapped cause after the colon: 'connection refused' means address/port; 'authentication handshake failed' or 'x509' means TLS config; 'deadline exceeded' means params.timeout.
- Verify the server with a plain client.invoke() call — if invoke also fails, the problem is in connect(), not the stream.
- For TLS servers, align connect params: remove plaintext:true, add tls: { cacerts: ... } (and cert/key for mTLS).
- Increase the stream timeout: client.newStream(method, { timeout: '30s' }) or set connect timeout.
- Confirm the method string exactly matches the proto service path and that the method is a server/client streaming RPC.
Example fix
// before
client.connect('grpc.example.com:443', { plaintext: true });
const stream = client.newStream('chat.ChatService/Connect'); // failed to create a new stream: ... handshake failure
// after
client.connect('grpc.example.com:443', { tls: { cacerts: [caPem] } });
const stream = client.newStream('chat.ChatService/Connect', { timeout: '30s' }); Defensive patterns
Strategy: try-catch
Validate before calling
// Cheap connectivity pre-check is not possible for gRPC streams; validate configuration instead.
function assertStreamConfig(client, method) {
if (!method.startsWith('/') || method.split('/').length !== 3) throw new Error(`invalid gRPC method '${method}', expected '/pkg.Service/Method'`);
} Try / catch
try {
const stream = client.newStream('/svc.Method/stream', { timeout: '30s' });
stream.on('error', (e) => console.log(`stream error: ${e}`));
} catch (err) {
const cause = String(err.message).split(':').pop().trim();
if (/refused|unavailable/.test(cause)) { /* server down: record failure, abort scenario */ }
else if (/handshake|x509/.test(cause)) { /* TLS config: fix connect params */ }
else if (/deadline/.test(cause)) { /* raise timeout and retry once */ }
} Prevention
- Prove the channel with a simple client.invoke() health call before opening streams.
- Always set an explicit stream timeout sized for handshake + first message.
- Register an 'error' listener on every stream so transport errors surface as events, not surprises.
When it happens
Trigger: Server is down or the address/port is wrong (rpc error: connection refused); TLS mismatch — e.g. connecting with plaintext:true to a TLS endpoint or vice versa; calling newStream before a successful client.connect(); a params.timeout that expires during stream setup (context deadline exceeded); the method name not matching a loaded service (stream mode on a method that is not a streaming RPC).
Common situations: Load testing a staging gRPC service that requires mTLS (missing tls.cert/key in connect params); typo in the method string ('/pkg.Service/Method' format); server behind a proxy that breaks HTTP/2; timeout set too low for slow TLS handshakes; reusing a client whose connection was closed after a prior error.
Related errors
- failed to dial: %w
- failed to decode PEM key
- encrypted pkcs8 formatted key is not supported
- failed to create dial options: %w
- failed to ingest request metadatas batch: code=%s, msg=%s
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/5a63ce31fbdbd29a.
Report an issue: GitHub.