{"record":{"id":"df0ae7f0840edf3e","repo":"apache/beam","slug":"failed-to-get-job","errorCode":null,"errorMessage":"failed to get job","messagePattern":"failed to get job","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/runners/dataflow/dataflowlib/job.go","lineNumber":270,"sourceCode":"\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tjob.ReplaceJobId = runningJob.Id\n\t}\n\tupd, err := client.Projects.Locations.Jobs.Create(project, region, job).Do()\n\tif err == nil {\n\t\tlog.Infof(ctx, \"Submitted job: %v\", upd.Id)\n\t}\n\treturn upd, err\n}\n\n// WaitForCompletion monitors the given job until completion. It logs any messages\n// and state changes received.\nfunc WaitForCompletion(ctx context.Context, client *df.Service, project, region, jobID string) error {\n\tfor {\n\t\tj, err := client.Projects.Locations.Jobs.Get(project, region, jobID).Do()\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"failed to get job\")\n\t\t}\n\n\t\tterminal, msg, err := currentStateMessage(j.CurrentState, jobID)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tlog.Infof(ctx, \"%s\", msg)\n\t\tif terminal {\n\t\t\treturn nil\n\t\t}\n\n\t\ttime.Sleep(30 * time.Second)\n\t}\n}\n\n// currentStateMessage indicates if the state is terminal, and provides a message to log, or an error.\n// Errors are always terminal.\nfunc currentStateMessage(currentState, jobID string) (bool, string, error) {","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/runners/dataflow/dataflowlib/job.go#L252-L288","documentation":"WaitForCompletion polls the Dataflow API (projects.locations.jobs.get) in a loop until the job reaches a terminal state. If any individual polling request fails, the error is wrapped with 'failed to get job' and returned, terminating monitoring. This means the SDK could not read the job's current status.","triggerScenarios":"Running a pipeline to completion (Execute calls WaitForCompletion) when a jobs.Get poll fails: transient API 5xx, network drop, deleted job, wrong region, or revoked permissions mid-run.","commonSituations":"Long-running streaming jobs hitting a transient Google API outage during polling, the job being deleted via console/gcloud while the pipeline waits, credentials expiring during very long jobs, or the region being wrong after a job move.","solutions":["Retry the pipeline run or add retry/backoff around job monitoring; single poll failures are often transient","Confirm the job still exists and the project/region match where it was launched","Check the service account retains dataflow.jobs.get permission for the job's lifetime","Inspect the wrapped cause's HTTP status: 404 → job deleted/wrong region, 403 → permissions, 5xx/timeout → transient"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := run(); err != nil && strings.Contains(err.Error(), \"failed to get job\") {\n    // inspect wrapped status: 404 job gone, 403 perms, 5xx transient\n    log.Printf(\"job monitoring failed: %v\", err)\n}","preventionTips":["Use retry/backoff for job status polling instead of failing on the first error","Keep credentials valid for the full job duration (long streaming jobs)","Confirm the job is not deleted externally while the pipeline waits","Pre-verify project and region before launching"],"tags":["go","dataflow","polling","api"],"backgroundTag":"api-request-failed","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"}