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
- Ensure the endpoint string includes a valid protocol, e.g. 'https://storage.googleapis.com/'
- Trim whitespace and remove quotes/typos from the configured URL
- 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
- Always include scheme (https://) in custom endpoints
- Validate endpoint strings at config-load time
- Trim and quote-check values from environment/YAML config
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
- Could not parse pubsub root url "%s"
- Could not determine port for pubsub root url "%s". You must
- Unrecognized value for stable unique names:
- No filesystem found for scheme
- Exploded field %s must be an iterable type, got %s.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/23c27a4648705a7e.
Report an issue: GitHub.