apache/beam · error · RuntimeException

Error creating URI '" + providedUrl + "' from a list of " +…

Error message

Error creating URI '" + providedUrl + "' from a list of " + providedUrls.size() + " URLs

What it means

Same URI parsing as the single-URL case, but for the URL list supplied via .withUrls(...). One entry in the list fails new URI(...) and buildDriver throws a RuntimeException naming the bad entry and the total list size, so you can find which of N configured servers is malformed.

Solutions

  1. Fix the named entry to a valid URI with scheme, e.g. neo4j+s://host:7687.
  2. Sanitize the list before building: filter/split on commas and trim each entry, dropping blanks.
  3. Pre-validate every entry with URI.create(entry) in your pipeline setup to fail with your own clearer message.
  4. Check env/config interpolation so no entry remains an unresolved placeholder like ${NEO4J_URL_2}.

Example fix

// before
.withUrls(Arrays.asList(" neo4j://a:7687", "b:7687"))
// after
.withUrls(Arrays.asList("neo4j://a:7687", "neo4j://b:7687"))
Defensive patterns

Strategy: validation

Validate before calling

List<String> urls = getProvidedValue(getUrls());
if (urls != null) {
  for (String u : urls) {
    try { new URI(u); } catch (URISyntaxException e) {
      throw new IllegalArgumentException("Invalid neo4j URL in list: '" + u + "'");
    }
  }
}

Type guard

static List<URI> parseUrls(List<String> urls) {
  return urls.stream().map(String::trim).filter(s -> !s.isEmpty()).map(u -> {
    try { return new java.net.URI(u); } catch (URISyntaxException e) { throw new IllegalArgumentException(u, e); }
  }).collect(java.util.stream.Collectors.toList());
}

Try / catch

try {
  pipeline.apply(Neo4jIO.read()...);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Error creating URI")) {
    throw new IllegalArgumentException("One of the withUrls entries is malformed: " + e.getMessage());
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a list of cluster addresses via .withUrls(Arrays.asList(...)) where at least one entry lacks a valid scheme or contains illegal characters; executed during expand -> buildDriver when creating the Neo4j driver.

Common situations: Comma-separated cluster strings split into entries that keep stray spaces; mixed valid/bolt URLs with an accidental http:// or empty string entry; unresolved placeholders in one of the entries from environment config.

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

Appendix: source

Thrown at sdks/java/io/neo4j/src/main/java/org/apache/beam/sdk/io/neo4j/Neo4jIO.java:398

      // Get the list of the URI to connect with
      //
      List<URI> uris = new ArrayList<>();
      String url = getProvidedValue(getUrl());
      if (url != null) {
        try {
          uris.add(new URI(url));
        } catch (URISyntaxException e) {
          throw new RuntimeException("Error creating URI from URL '" + url + "'", e);
        }
      }
      List<String> providedUrls = getProvidedValue(getUrls());
      if (providedUrls != null) {
        for (String providedUrl : providedUrls) {
          try {
            uris.add(new URI(providedUrl));
          } catch (URISyntaxException e) {
            throw new RuntimeException(
                "Error creating URI '"
                    + providedUrl
                    + "' from a list of "
                    + providedUrls.size()
                    + " URLs",
                e);
          }
        }
      }

      // A specific routing driver can be used to connect to specific clustered configurations.
      // Often we don't need it because the Java driver automatically can figure this out
      // automatically. To keep things simple we use the routing driver in case we have more
      // than one URL specified.  This is an exceptional case.
      //
      Driver driver;
      AuthToken authTokens =
          getAuthToken(getProvidedValue(getUsername()), getProvidedValue(getPassword()));

View on GitHub (pinned to 12126d8942)