apache/seatunnel · error · SeaTunnelRuntimeException
Invalid table URL format: '%s'. Expected format: http://host
Error message
Invalid table URL format: '%s'. Expected format: http://host/api/metalakes/{metalake}/catalogs/{catalog}/schemas/{schema}/tables/{table} What it means
SeaTunnelRuntimeException (ERROR_INVALID_TABLE_URL) thrown by GravitinoClient.getMatcher when the schemaHttpUrl does not match TABLE_URL_PATTERN, i.e. it is not of the form http://host/api/metalakes/{metalake}/catalogs/{catalog}/schemas/{schema}/tables/{table}.
Source
Thrown at seatunnel-api/src/main/java/org/apache/seatunnel/api/metalake/gravitino/GravitinoClient.java:116
}
@Override
public TablePath getTableSchemaPath(String schemaHttpUrl) {
if (schemaHttpUrl == null || schemaHttpUrl.isEmpty()) {
throw new SeaTunnelRuntimeException(
ERROR_INVALID_TABLE_URL, "Table URL cannot be null or empty");
}
final Matcher matcher = getMatcher(schemaHttpUrl);
String catalogName = matcher.group(1);
String schemaName = matcher.group(2);
String tableName = matcher.group(3);
return TablePath.of(catalogName, schemaName, tableName);
}
private Matcher getMatcher(String schemaHttpUrl) {
Matcher matcher = TABLE_URL_PATTERN.matcher(schemaHttpUrl);
if (!matcher.find()) {
throw new SeaTunnelRuntimeException(
ERROR_INVALID_TABLE_URL,
String.format(
"Invalid table URL format: '%s'. "
+ "Expected format: http://host/api/metalakes/{metalake}/catalogs/{catalog}/schemas/{schema}/tables/{table}",
schemaHttpUrl));
}
return matcher;
}
/**
* Execute HTTP GET request and return parsed JSON response. Implements retry with exponential
* backoff for transient failures.
*
* @param url the request URL
* @return parsed JSON root node
*/
private JsonNode executeGetRequest(String url) {
for (int attempt = 1; attempt <= MAX_RETRY_ATTEMPTS; attempt++) {View on GitHub (pinned to cf67b549a7)
Solutions
- Pass the exact table URL: http(s)://host/api/metalakes/{metalake}/catalogs/{catalog}/schemas/{schema}/tables/{table}.
- Check for trailing slashes or query strings and remove them.
- If your server uses a custom path prefix, verify it matches the regex TABLE_URL_PATTERN or normalize the URL before calling.
- Log/print the offending URL and test it against the expected regex.
Example fix
// before
client.getTableSchemaPath("http://host/api/metalakes/m1/catalogs/c1/schemas/s1");
// after
client.getTableSchemaPath("http://host/api/metalakes/m1/catalogs/c1/schemas/s1/tables/t1"); Defensive patterns
Strategy: validation
Validate before calling
static final Pattern P = Pattern.compile("https?://[^/]+/api/metalakes/[^/]+/catalogs/[^/]+/schemas/[^/]+/tables/[^/]+/?$");
static boolean isValidTableUrl(String u) { return u != null && P.matcher(u).matches(); }
// if (!isValidTableUrl(tableUrl)) throw new IllegalArgumentException(tableUrl); Try / catch
try {
return client.getTableSchemaPath(url);
} catch (SeaTunnelRuntimeException e) {
if (e.getMessage().startsWith("Invalid table URL format")) {
LOG.error("URL {} does not match expected Gravitino table URL shape", url);
}
throw e;
} Prevention
- Store full table URLs (through /tables/{table}), not catalog/schema URLs.
- Strip trailing slashes and query strings before calling.
- Normalize versioned API prefixes to match the expected pattern.
- Unit-test URL construction with real Gravitino examples.
When it happens
Trigger: Calling getTableSchemaPath (directly or via tableSchema flows) with a URL missing the /api/metalakes/ path, using a different API version path, having trailing segments, or pointing at a non-table resource (e.g. a catalogs or schemas URL).
Common situations: Configured Gravitino server uses a versioned or proxied path prefix; user pasted the catalog or schema URL instead of the table URL; trailing slash or query string appended; HTTP vs HTTPS host mismatch is fine but path changes are not.
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
- Table URL cannot be null or empty
- Invalid metalake table id:
- Invalid Firebase REST URI constructed. Check parameter forma
- Invalid DuckDB JDBC url:
- Condition operator must not be null
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/5516109eb8c3cd9d.
Report an issue: GitHub.