{"record":{"id":"3107c1072ba42752","repo":"apache/beam","slug":"request-to-s-failed-with-status-d-s-spark-uber-jar-job","errorCode":null,"errorMessage":"Request to %s failed with status %d: %s","messagePattern":"Request to (.+?) failed with status (.+?): (.+?)","errorType":"http","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/runners/portability/spark_uber_jar_job_server.py","lineNumber":126,"sourceCode":"      pipeline,\n      options,\n      artifact_port=0):\n    super().__init__(\n        executable_jar,\n        job_id,\n        job_name,\n        pipeline,\n        options,\n        artifact_port=artifact_port)\n    self._rest_url = rest_url\n    # Message history is a superset of state history.\n    self._message_history = self._state_history[:]\n\n  def request(self, method, path, expected_status=200, **kwargs):\n    url = '%s/%s' % (self._rest_url, path)\n    response = method(url, **kwargs)\n    if response.status_code != expected_status:\n      raise RuntimeError(\n          \"Request to %s failed with status %d: %s\" %\n          (url, response.status_code, response.text))\n    if response.text:\n      return response.json()\n\n  def get(self, path, **kwargs):\n    return self.request(requests.get, path, **kwargs)\n\n  def post(self, path, **kwargs):\n    return self.request(requests.post, path, **kwargs)\n\n  def delete(self, path, **kwargs):\n    return self.request(requests.delete, path, **kwargs)\n\n  def _get_server_spark_version(self):\n    # Spark REST API doesn't seem to offer a dedicated endpoint for getting the\n    # version, but it does include the version in all responses, even errors.\n    return self.get('', expected_status=400)['serverSparkVersion']","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/runners/portability/spark_uber_jar_job_server.py#L108-L144","documentation":"SparkUberJarJobServer.request wraps all REST calls (get/post/delete) to the Spark cluster and raises RuntimeError whenever the HTTP response status differs from the expected one (default 200), including the URL, actual status, and response body for diagnosis.","triggerScenarios":"Any REST interaction with the Spark cluster returning a non-expected status: submitting the job (bad jar path or master), polling status of a failed/killed app (404 once the app is purged from history), DELETE during cancellation, wrong expected_status passed by the caller.","commonSituations":"Spark REST service unreachable or behind a proxy returning 404/502; application already finished and removed so status polling 404s; wrong port (REST port vs UI port); cluster returned 500 due to submission failure (bad master URL, missing files).","solutions":["Inspect the embedded response body for the Spark error detail (submission failures usually explain themselves).","Verify spark_rest_url points at the REST endpoint (standalone: http://master:6066 or :8080 cluster UI API), not the UI or driver port.","Handle 404 on status polling as 'job finished and purged' rather than a fatal error, or pass expected_status accordingly.","Check network/proxy/firewall between the driver and the Spark cluster; retry transient 5xx.","Ensure the uber jar and staged files are reachable from the cluster to avoid submission-time 500s."],"exampleFix":"// before\nstatus = job_server.get('v1/submissions/status/' + submission_id)  # may 404 after purge\n// after\ntry:\n    status = job_server.get('v1/submissions/status/' + submission_id)\nexcept RuntimeError as e:\n    if 'status 404' in str(e):\n        status = {'submissionState': 'FINISHED'}  # treat purged app as finished\n    else:\n        raise","handlingStrategy":"try-catch","validationCode":"import requests\nprobe = requests.get(f'{rest_url.rstrip(chr(47))}/v1/applications', timeout=5)\nprobe.raise_for_status()  # confirm REST endpoint is healthy before submitting","typeGuard":null,"tryCatchPattern":"try:\n    status = server.get(f'v1/submissions/status/{submission_id}')\nexcept RuntimeError as e:\n    if 'status 404' in str(e):\n        status = {'submissionState': 'FINISHED'}\n    elif 'status 5' in str(e):\n        retry_with_backoff()\n    else:\n        raise","preventionTips":["Point spark_rest_url at the REST port, not the UI port","Treat 404-after-purge as job completion in pollers","Add retry/backoff for transient 5xx","Check the response body embedded in the error for the Spark failure reason"],"tags":["apache-beam","spark","http","rest"],"backgroundTag":"http-error-response","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"}