{"record":{"id":"4893e45bae8af964","repo":"apache/beam","slug":"unable-to-dial-sdk-worker-pool-v-v","errorCode":null,"errorMessage":"unable to dial sdk worker pool %v: %v","messagePattern":"unable to dial sdk worker pool (.+?): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/runners/prism/internal/environments.go","lineNumber":129,"sourceCode":"\t\trankB := ranks[b.GetUrn()]\n\n\t\t// Reverse the comparison so our favourite is at the front\n\t\tswitch {\n\t\tcase rankA > rankB:\n\t\t\treturn -1 // Usually \"greater than\" would be 1\n\t\tcase rankA < rankB:\n\t\t\treturn 1\n\t\t}\n\t\treturn 0\n\t})\n\t// Pick our favourite.\n\treturn envs[0]\n}\n\nfunc externalEnvironment(ctx context.Context, ep *pipepb.ExternalPayload, wk *worker.W) {\n\tconn, err := grpc.Dial(ep.GetEndpoint().GetUrl(), grpc.WithTransportCredentials(insecure.NewCredentials()))\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"unable to dial sdk worker pool %v: %v\", ep.GetEndpoint().GetUrl(), err))\n\t}\n\tdefer conn.Close()\n\tpool := fnpb.NewBeamFnExternalWorkerPoolClient(conn)\n\n\tendpoint := &pipepb.ApiServiceDescriptor{\n\t\tUrl: wk.Endpoint(),\n\t}\n\n\t// Use a background context for these workers to avoid pre-mature\n\t// cancelation issues when starting them.\n\tbgContext := context.Background()\n\n\tresp, err := pool.StartWorker(bgContext, &fnpb.StartWorkerRequest{\n\t\tWorkerId:          wk.ID,\n\t\tControlEndpoint:   endpoint,\n\t\tLoggingEndpoint:   endpoint,\n\t\tArtifactEndpoint:  endpoint,\n\t\tProvisionEndpoint: endpoint,","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/runners/prism/internal/environments.go#L111-L147","documentation":"externalEnvironment dials the external SDK worker pool's gRPC endpoint from the ExternalPayload. If grpc.Dial fails to establish a connection to the given URL, prism panics with this message including the endpoint URL and the underlying gRPC error.","triggerScenarios":"Running a pipeline whose environment is an external (pre-spawned) worker pool whose endpoint URL is wrong, unreachable, or the worker pool process is not listening at that address.","commonSituations":"Typo in --environment_config endpoint, external worker pool crashed or never started, firewall/network policy blocking the port, or TLS/insecure credential mismatch.","solutions":["Confirm the external worker pool is running and listening on the URL in the ExternalPayload (curl/nc the host:port).","Fix the endpoint URL in the environment configuration (scheme, host, port).","Check network/firewall rules and ensure prism can reach the worker pool host.","Ensure credentials match (insecure vs TLS) on both runner and pool sides."],"exampleFix":"// before\n\"environment_config\": \"{\\\"endpoint\\\":\\\"grpc://localhost:50001\\\"}\" // pool actually on 50002\n// after\n\"environment_config\": \"{\\\"endpoint\\\":\\\"grpc://localhost:50002\\\"}\"","handlingStrategy":"validation","validationCode":"// Before submitting, check the external worker pool endpoint is reachable\nconn, err := net.DialTimeout(\"tcp\", hostPortFromURL(endpointURL), 5*time.Second)\nif err != nil {\n    return fmt.Errorf(\"worker pool endpoint %s unreachable: %w\", endpointURL, err)\n}\nconn.Close()","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify the endpoint URL in environment_config before launching jobs","Ensure the external worker pool process is up before submitting pipelines","Check firewall/localhost port availability"],"tags":["go","grpc","network","panic","worker-pool"],"backgroundTag":"connection-refused","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}