apache/beam · error · ValueError

Unable to parse jar URL "%s". If using a full URL, make sure

Error message

Unable to parse jar URL "%s". If using a full URL, make sure the scheme is specified. If using a local file path, make sure the file exists; you may have to first build the job server using `./gradlew runners:flink:%s:job-server:shadowJar`.

What it means

FlinkUberJarJobServer.executable_jar validates the configured job-server jar: if the path does not exist on disk and is not a URL with a scheme, it raises ValueError. It first attempts flink_version() to interpolate a concrete version into the gradle build hint, falling back to the literal '$FLINK_VERSION' if that probe fails.

Source

Thrown at sdks/python/apache_beam/runners/portability/flink_uber_jar_job_server.py:71

        options.view_as(pipeline_options.JobServerOptions).artifact_port)
    self._temp_dir = tempfile.mkdtemp(prefix='apache-beam-flink')

  def start(self):
    return self

  def stop(self):
    pass

  def executable_jar(self):
    if self._executable_jar:
      if not os.path.exists(self._executable_jar):
        parsed = urllib.parse.urlparse(self._executable_jar)
        if not parsed.scheme:
          try:
            flink_version = self.flink_version()
          except Exception:
            flink_version = '$FLINK_VERSION'
          raise ValueError(
              'Unable to parse jar URL "%s". If using a full URL, make sure '
              'the scheme is specified. If using a local file path, make sure '
              'the file exists; you may have to first build the job server '
              'using `./gradlew runners:flink:%s:job-server:shadowJar`.' %
              (self._executable_jar, flink_version))
      url = self._executable_jar
    else:
      url = job_server.JavaJarJobServer.path_to_beam_jar(
          ':runners:flink:%s:job-server:shadowJar' % self.flink_version())
    return job_server.JavaJarJobServer.local_jar(
        url, user_agent=self._user_agent)

  def flink_version(self):
    full_version = requests.get(
        '%s/v1/config' % self._master_url, timeout=60).json()['flink-version']
    # Only return up to minor version.
    return '.'.join(full_version.split('.')[:2])

View on GitHub (pinned to 12126d8942)

Solutions

  1. Build the matching jar: `./gradlew runners:flink:<version>:job-server:shadowJar` and point executable_jar at it.
  2. Supply a full URL with scheme (file:///path or http://...) if the jar lives remotely.
  3. Check the configured path exists and matches the cluster's Flink version.

Example fix

// before
FlinkUberJarJobServer(master_url=..., executable_jar='/opt/beam/job-server.jar')
// after
FlinkUberJarJobServer(
    master_url=...,
    executable_jar='file:///opt/beam/beam-runners-flink-1.17-job-server.jar')
Defensive patterns

Strategy: validation

Validate before calling

import os
jar = executable_jar
if jar and not os.path.exists(jar) and '://' not in jar:
    raise FileNotFoundError(
        f"build it: ./gradlew runners:flink:<ver>:job-server:shadowJar ({jar})")

Try / catch

try:
    server = FlinkUberJarJobServer(master_url=..., executable_jar=jar)
    server.create_beam_job(...)
except ValueError as e:
    if 'Unable to parse jar URL' in str(e):
        build_job_server_jar()
        server = FlinkUberJarJobServer(
            master_url=..., executable_jar=built_jar_path())
    else:
        raise

Prevention

When it happens

Trigger: Constructing/using FlinkUberJarJobServer with an executable_jar that neither exists locally nor has a URL scheme; the '$FLINK_VERSION' placeholder in the message means even the version probe failed (jar absent).

Common situations: Passing --flink_job_server_jar a path where the shadowJar was never built; version mismatch between installed Flink and the built job-server jar; jobservers on machines without gradle builds.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/edc4f8419ce5cf79. Report an issue: GitHub.