apache/beam · error · RuntimeError

Artifact not found at

Error message

Artifact not found at %s (response: %s)

What it means

Stager._download_file downloads an artifact over HTTP and explicitly checks the response status because wget-style helpers can return content even for 404s. If the HTTP status is >= 400 it raises this RuntimeError including the raw response object.

Solutions

  1. Verify the URL is downloadable: curl -I <from_url> and expect 200
  2. Fix the URL/version in jar_packages to an artifact that exists in the repository
  3. Add authentication or use a repository mirror if the artifact requires credentials
  4. Upload the jar to an accessible location or stage it as a local file instead

Example fix

// before
--experiment=jar_packages=https://repo.example.com/libs/my-lib-1.2.jar
// after
--experiment=jar_packages=https://repo1.maven.org/maven2/com/example/my-lib/1.2/my-lib-1.2.jar
Defensive patterns

Strategy: validation

Validate before calling

import urllib.request
req = urllib.request.Request(url, method='HEAD')
with urllib.request.urlopen(req) as r:
    if r.status != 200:
        raise SystemExit(f'Artifact URL not downloadable: {url} ({r.status})')

Try / catch

try:
    stager.create_and_stage_job_resources(setup_options)
except RuntimeError as e:
    if 'Artifact not found at' in str(e):
        sys.exit(f'Artifact URL unreachable: {e}')
    raise

Prevention

When it happens

Trigger: _download_file (used for jar_packages and other remote artifacts) fetches a URL and the server returns status 400+ (404 missing artifact, 403 denied, 5xx).

Common situations: --experiment=jar_packages=<https url> pointing at a nonexistent jar in a Maven/Nexus repo; expired or unauthorized artifact URL; internal repo requiring credentials; DNS/proxy returning an error page with a 4xx/5xx status.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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

Appendix: source

Thrown at sdks/python/apache_beam/runners/portability/stager.py:515

    shutil.rmtree(temp_dir)
    retrieval_token = self.commit_manifest()
    return retrieval_token, staged_resources

  @staticmethod
  @retry.with_exponential_backoff(num_retries=4)
  def _download_file(from_url, to_path):
    """Downloads a file over http/https from a url or copy it from a remote
        path to local path."""
    if from_url.startswith('http://') or from_url.startswith('https://'):
      # TODO(silviuc): We should cache downloads so we do not do it for every
      # job.
      try:
        # We check if the file is actually there because wget returns a file
        # even for a 404 response (file will contain the contents of the 404
        # response).
        response, content = get_new_http().request(from_url)
        if int(response['status']) >= 400:
          raise RuntimeError(
              'Artifact not found at %s (response: %s)' % (from_url, response))
        with open(to_path, 'wb') as f:
          f.write(content)
      except Exception:
        _LOGGER.info('Failed to download Artifact from %s', from_url)
        raise
    else:
      try:
        read_handle = FileSystems.open(
            from_url, compression_type=CompressionTypes.UNCOMPRESSED)
        with read_handle as fin:
          with open(to_path, 'wb') as f:
            while True:
              chunk = fin.read(Stager._DEFAULT_CHUNK_SIZE)
              if not chunk:
                break
              f.write(chunk)
        _LOGGER.info('Copied remote file from %s to %s.', from_url, to_path)

View on GitHub (pinned to 12126d8942)