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

FlinkRunnerOptions.path_to_jar resolves the Flink job-server jar. If the configured jar path does not exist on disk, the code treats it as possibly a URL; with no URL scheme it can be neither a file nor a URL, so it raises ValueError and hints at the gradle build command.

Source

Thrown at sdks/python/apache_beam/runners/portability/flink_runner.py:102

          flink_master)
      flink_master = 'http://' + flink_master
    return flink_master


class FlinkJarJobServer(job_server.JavaJarJobServer):
  def __init__(self, options):
    super().__init__(options)
    options = options.view_as(pipeline_options.FlinkRunnerOptions)
    self._jar = options.flink_job_server_jar
    self._master_url = options.flink_master
    self._flink_version = options.flink_version

  def path_to_jar(self):
    if self._jar:
      if not os.path.exists(self._jar):
        url = urllib.parse.urlparse(self._jar)
        if not url.scheme:
          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._jar, self._flink_version))
      return self._jar
    else:
      return self.path_to_beam_jar(
          ':runners:flink:%s:job-server:shadowJar' % self._flink_version)

  def java_arguments(
      self, job_port, artifact_port, expansion_port, artifacts_dir):
    return [
        '--flink-master',
        self._master_url,
        '--artifacts-dir',
        artifacts_dir,
        '--job-port',

View on GitHub (pinned to 12126d8942)

Solutions

  1. Build the job server: `./gradlew runners:flink:<flink_version>:job-server:shadowJar`.
  2. Pass --flink_job_server_jar with an existing absolute path, or a full URL including a scheme (file:///, http://).
  3. Verify the path exists (ls/os.path.exists) and fix typos or stale version numbers.

Example fix

// before
--flink_job_server_jar /opt/flink/job-server.jar  # missing file, no scheme
// after
./gradlew runners:flink:1.17:job-server:shadowJar
--flink_job_server_jar /opt/beam/beam-runners-flink-1.17-job-server.jar
Defensive patterns

Strategy: validation

Validate before calling

import os
jar = pipeline_options.view_as(FlinkRunnerOptions).flink_job_server_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:
    run_flink_pipeline(options)
except ValueError as e:
    if 'Unable to parse jar URL' in str(e):
        build_job_server_jar()  # gradle shadowJar
        run_flink_pipeline(options)
    else:
        raise

Prevention

When it happens

Trigger: Running a Flink pipeline with --flink_job_server_jar (or a default path) pointing to a nonexistent local file that contains no '://' scheme — typically a jar that was never built.

Common situations: Fresh checkout without building `./gradlew runners:flink:<version>:job-server:shadowJar`; typo in the jar path; Flink version changed so the versioned jar filename no longer matches.

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/8cdc7698669b085c. Report an issue: GitHub.