grafana/k6 · error

failed to create dial options: %w

Error message

failed to create dial options: %w

What it means

The insights gRPC client (internal/cloudapi/insights/client.go:143-147) builds its dial options from ClientConfig via dialOptionsFromClientConfig before calling grpc.DialContext. Any failure in that construction is wrapped as 'failed to create dial options'. In practice the wrapped cause is one of two things further down the same file: loading the TLS cert file (line 226-229) or building the retry interceptor from RetryConfig (line 240-243, itself usually a retryable-status-codes parse error).

Source

Thrown at internal/cloudapi/insights/client.go:145

		cfg:    cfg,
		client: nil,
		conn:   nil,
		connMu: &sync.RWMutex{},
	}
}

// Dial creates a client connection using ClientConfig.
func (c *Client) Dial(ctx context.Context) error {
	c.connMu.Lock()
	defer c.connMu.Unlock()

	if c.conn != nil {
		return ErrClientAlreadyInitialized
	}

	opts, err := dialOptionsFromClientConfig(c.cfg)
	if err != nil {
		return fmt.Errorf("failed to create dial options: %w", err)
	}

	ctx, cancel := context.WithTimeout(ctx, c.cfg.ConnectConfig.Timeout)
	defer cancel()

	conn, err := grpc.DialContext(ctx, c.cfg.IngesterHost, opts...) //nolint:staticcheck
	if err != nil {
		return fmt.Errorf("failed to dial: %w", err)
	}

	c.client = ingester.NewIngesterServiceClient(conn)
	c.conn = conn

	return nil
}

// IngestRequestMetadatasBatch ingests a batch of request metadatas.
func (c *Client) IngestRequestMetadatasBatch(ctx context.Context, requestMetadatas RequestMetadatas) error {

View on GitHub (pinned to 93accf6570)

Solutions

  1. Read the wrapped error - it names the real cause ('failed to load TLS credentials from file: ...' or 'failed to parse retryable status codes: ...')
  2. If TLS: verify the cert file path is readable from k6's working context and is a valid PEM bundle
  3. If retry codes: set a valid comma-separated list of gRPC code names, e.g. 'Unavailable,ResourceExhausted', or remove the override to use defaults
  4. Update k6 so the insights config format matches what the backend/orchestrator emits

Example fix

# before - orchestrator exports a broken override
export K6_CLOUD_API_RETRY_RETRYABLE_STATUS_CODES='unavailable'

# after - valid gRPC code names, or unset for defaults
export K6_CLOUD_API_RETRY_RETRYABLE_STATUS_CODES='Unavailable'
Defensive patterns

Strategy: validation

Validate before calling

// Go embedder: construct dial options separately to fail with the precise error before Dial
if _, err := insightsclient.NewClient(...).Dial(ctx); err != nil {
    // unwrap: errors.Unwrap(err) distinguishes TLS vs retry-config causes
    log.Printf("insights dial failed, cause: %v", errors.Unwrap(err))
}

Try / catch

if err := c.Dial(ctx); err != nil {
    if strings.HasPrefix(err.Error(), "failed to create dial options") {
        // configuration defect, not a network issue - fix cert file or retry codes before retrying
    }
    return err
}

Prevention

When it happens

Trigger: Insights enabled with TLSConfig.CertFile pointing at a missing or non-PEM file; RetryConfig.RetryableStatusCodes empty or containing invalid gRPC code names; config supplied by an orchestrator via env (K6_CLOUD_API_* / push-credentials flow) with a bad value.

Common situations: Self-hosted or private-link insights ingestion with a custom CA whose path is wrong inside a container; an orchestrator overriding retry settings with typo'd code names like 'unavailable ' (lowercase/trailing space); an update that changed defaults while a pinned env override kept an old format.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/5b8c2debb81d273c. Report an issue: GitHub.