prestodb/presto · error · RuntimeException

RuntimeException(e)

Error message

RuntimeException(e)

What it means

PrometheusClient.getPrometheusMetricsURI derives the metrics-list endpoint URI by recombining scheme, authority, and path of the configured Prometheus URI with the METRICS_ENDPOINT suffix. Because URI's multi-argument constructor validates its parts, a malformed configured prometheus URI (illegal characters, bad authority, etc.) throws URISyntaxException, which is wrapped in a bare RuntimeException.

Source

Thrown at presto-prometheus/src/main/java/com/facebook/presto/plugin/prometheus/PrometheusClient.java:100

        requireNonNull(typeManager, "typeManager is null");

        bearerTokenFile = config.getBearerTokenFile();
        URI prometheusMetricsUri = getPrometheusMetricsURI(config.getPrometheusURI());
        tableSupplier = Suppliers.memoizeWithExpiration(
                () -> fetchMetrics(metricCodec, prometheusMetricsUri),
                config.getCacheDuration().toMillis(),
                MILLISECONDS);
        varcharMapType = typeManager.getType(mapType(VARCHAR.getTypeSignature(), VARCHAR.getTypeSignature()));
    }

    private static URI getPrometheusMetricsURI(URI prometheusUri)
    {
        try {
            // endpoint to retrieve metric names from Prometheus
            return new URI(prometheusUri.getScheme(), prometheusUri.getAuthority(), prometheusUri.getPath() + METRICS_ENDPOINT, null, null);
        }
        catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

    public Set<String> getTableNames(String schema)
    {
        requireNonNull(schema, "schema is null");
        String status = "";
        if (schema.equals("default")) {
            if (!tableSupplier.get().isEmpty()) {
                Object tableSupplierStatus = tableSupplier.get().get("status");
                if (tableSupplierStatus instanceof String) {
                    status = (String) tableSupplierStatus;
                }
            }

            //TODO prometheus warnings (success|error|warning) could be handled separately
            if (status.equals("success")) {
                List<String> tableNames = (List<String>) tableSupplier.get().get("data");

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check the prometheus-uri property in the catalog config for typos or illegal characters
  2. Use a plain form like http://prometheus-host:9090 with no query string or fragment
  3. URL-encode any special characters in host/path components
  4. Look at the wrapped URISyntaxException cause in the stack trace for the exact offending index/character

Example fix

// before
prometheus-uri=http://prometheus host:9090
// after
prometheus-uri=http://prometheus-host:9090
Defensive patterns

Strategy: validation

Validate before calling

java
String uri = catalogProps.getProperty("prometheus-uri");
new URI(uri); // throws URISyntaxException at config load if malformed
Objects.requireNonNull(uri, "prometheus-uri is required");

Try / catch

java
try {
    Set<String> tables = client.getTableNames("default");
} catch (RuntimeException e) {
    if (e.getCause() instanceof URISyntaxException) {
        log.error("Fix prometheus-uri config: " + e.getCause().getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: prometheusMetricsUri is called with a prometheus-uri config value that produces an invalid URI when the metrics endpoint path is appended — e.g. characters needing escaping, malformed authority, or an unexpected path shape.

Common situations: Config values with unescaped spaces or unicode, a prometheus-uri including a query/fragment that doesn't recombine cleanly, typos like 'http://prometheus:9090//api' with path issues, or an empty/unset URI built from partial parts.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/d0535b58a830a904. Report an issue: GitHub.