{"record":{"id":"5b8c2debb81d273c","repo":"grafana/k6","slug":"failed-to-create-dial-options-w","errorCode":null,"errorMessage":"failed to create dial options: %w","messagePattern":"failed to create dial options: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cloudapi/insights/client.go","lineNumber":145,"sourceCode":"\t\tcfg:    cfg,\n\t\tclient: nil,\n\t\tconn:   nil,\n\t\tconnMu: &sync.RWMutex{},\n\t}\n}\n\n// Dial creates a client connection using ClientConfig.\nfunc (c *Client) Dial(ctx context.Context) error {\n\tc.connMu.Lock()\n\tdefer c.connMu.Unlock()\n\n\tif c.conn != nil {\n\t\treturn ErrClientAlreadyInitialized\n\t}\n\n\topts, err := dialOptionsFromClientConfig(c.cfg)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create dial options: %w\", err)\n\t}\n\n\tctx, cancel := context.WithTimeout(ctx, c.cfg.ConnectConfig.Timeout)\n\tdefer cancel()\n\n\tconn, err := grpc.DialContext(ctx, c.cfg.IngesterHost, opts...) //nolint:staticcheck\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to dial: %w\", err)\n\t}\n\n\tc.client = ingester.NewIngesterServiceClient(conn)\n\tc.conn = conn\n\n\treturn nil\n}\n\n// IngestRequestMetadatasBatch ingests a batch of request metadatas.\nfunc (c *Client) IngestRequestMetadatasBatch(ctx context.Context, requestMetadatas RequestMetadatas) error {","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/cloudapi/insights/client.go#L127-L163","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the wrapped error - it names the real cause ('failed to load TLS credentials from file: ...' or 'failed to parse retryable status codes: ...')","If TLS: verify the cert file path is readable from k6's working context and is a valid PEM bundle","If retry codes: set a valid comma-separated list of gRPC code names, e.g. 'Unavailable,ResourceExhausted', or remove the override to use defaults","Update k6 so the insights config format matches what the backend/orchestrator emits"],"exampleFix":"# before - orchestrator exports a broken override\nexport K6_CLOUD_API_RETRY_RETRYABLE_STATUS_CODES='unavailable'\n\n# after - valid gRPC code names, or unset for defaults\nexport K6_CLOUD_API_RETRY_RETRYABLE_STATUS_CODES='Unavailable'","handlingStrategy":"validation","validationCode":"// Go embedder: construct dial options separately to fail with the precise error before Dial\nif _, err := insightsclient.NewClient(...).Dial(ctx); err != nil {\n    // unwrap: errors.Unwrap(err) distinguishes TLS vs retry-config causes\n    log.Printf(\"insights dial failed, cause: %v\", errors.Unwrap(err))\n}","typeGuard":null,"tryCatchPattern":"if err := c.Dial(ctx); err != nil {\n    if strings.HasPrefix(err.Error(), \"failed to create dial options\") {\n        // configuration defect, not a network issue - fix cert file or retry codes before retrying\n    }\n    return err\n}","preventionTips":["Always read the wrapped cause - it distinguishes TLS file problems from retry-code problems","Validate custom CA bundles in the deployment pipeline with openssl before the run","Use exact CamelCase gRPC code names in any retry override"],"tags":["cloud","grpc","insights","tls","configuration"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}