apache/beam · error · RuntimeException

Invalid URL: %s

Error message

Invalid URL: %s

What it means

Transport.apiComponentsFromUrl parses an API root URL string into ApiComponents (rootUrl + path). If the string is not a valid URL per java.net.URL, the caught MalformedURLException is rethrown as a RuntimeException with the offending string.

Source

Thrown at sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/util/Transport.java:94

    public String servicePath;

    public ApiComponents(String root, String path) {
      this.rootUrl = root;
      this.servicePath = path;
    }
  }

  private static ApiComponents apiComponentsFromUrl(String urlString) {
    try {
      URL url = new URL(urlString);
      String rootUrl =
          url.getProtocol()
              + "://"
              + url.getHost()
              + (url.getPort() > 0 ? ":" + url.getPort() : "");
      return new ApiComponents(rootUrl, url.getPath());
    } catch (MalformedURLException e) {
      throw new RuntimeException("Invalid URL: " + urlString);
    }
  }

  /** Returns a Cloud Storage client builder using the specified {@link GcsOptions}. */
  public static Storage.Builder newStorageClient(GcsOptions options) {
    String applicationName =
        String.format(
            "%sapache-beam/%s (GPN:Beam)",
            isNullOrEmpty(options.getAppName()) ? "" : options.getAppName() + " ",
            ReleaseInfo.getReleaseInfo().getSdkVersion());

    String servicePath = options.getGcsEndpoint();

    Storage.Builder storageBuilder =
        new Storage.Builder(
                getTransport(), getJsonFactory(), httpRequestInitializerFromOptions(options))
            .setApplicationName(applicationName)
            .setGoogleClientRequestInitializer(options.getGoogleApiTrace());

View on GitHub (pinned to 12126d8942)

Solutions

  1. Ensure the endpoint string includes a valid protocol, e.g. 'https://storage.googleapis.com/'
  2. Trim whitespace and remove quotes/typos from the configured URL
  3. If set programmatically, validate with new URI(urlString) before passing it in

Example fix

// before
options.setGcsEndpoint("storage.googleapis.com");
// after
options.setGcsEndpoint("https://storage.googleapis.com");
Defensive patterns

Strategy: validation

Validate before calling

try { new java.net.URI(urlString); new java.net.URL(urlString); } catch (Exception e) { throw new IllegalArgumentException("Bad endpoint URL: " + urlString, e); }

Type guard

boolean isValidUrl(String s) { try { new java.net.URL(s); return true; } catch (java.net.MalformedURLException e) { return false; } }

Try / catch

try { components(urlString); } catch (RuntimeException e) { if (e.getMessage().startsWith("Invalid URL:")) { /* fix config and retry with validated URL */ } else throw e; }

Prevention

When it happens

Trigger: Passing a malformed urlString to apiComponentsFromUrl, e.g. a URL missing a protocol ('myhost/api') or containing illegal characters, typically via a misconfigured API root URL option.

Common situations: Users set a custom GCS/API endpoint (e.g. emulator or VPC endpoint) without the 'https://' scheme, or with a typo/whitespace in the endpoint string.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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