risingwavelabs/risingwave · error · ConnectorError
credentials_url must be a valid URL (s3://, file://) or an a
Error message
credentials_url must be a valid URL (s3://, file://) or an absolute file path
What it means
Raised by `resolve_pulsar_credentials_url` when a Pulsar OAuth2 `credentials_url` is neither a parseable URL with scheme file:// or s3://, nor an absolute filesystem path. The function tries URL parsing first, then falls back to `Path::is_absolute`; both failing means the value cannot be resolved to a credentials file.
Source
Thrown at src/connector/src/connector_common/common.rs:752
Ok(res)
}
pub(crate) async fn resolve_pulsar_credentials_url(
&self,
oauth: &PulsarOauthCommon,
aws_auth_props: &AwsAuthProps,
) -> ConnectorResult<(String, Option<NamedTempFile>)> {
// Try parsing as URL first
if let Ok(url) = Url::parse(&oauth.credentials_url) {
return self
.handle_pulsar_credentials_url(&url, aws_auth_props)
.await;
}
// If not a valid URL, check if it's an absolute file path
let path = Path::new(&oauth.credentials_url);
if !path.is_absolute() {
bail!("credentials_url must be a valid URL (s3://, file://) or an absolute file path");
}
// Verify the file exists
if !tokio::fs::try_exists(&oauth.credentials_url)
.await
.unwrap_or(false)
{
bail!("credentials file does not exist: {}", oauth.credentials_url);
}
// Return absolute path with file:// prefix
Ok((format!("file://{}", oauth.credentials_url), None))
}
pub(crate) async fn handle_pulsar_credentials_url(
&self,
url: &Url,
aws_auth_props: &AwsAuthProps,View on GitHub (pinned to 6469eb736d)
Solutions
- Use an absolute file path, e.g. `/etc/pulsar/creds.json`.
- Use a valid `file:///path/to/creds.json` or `s3://bucket/creds.json` URL.
- Fix scheme typos (e.g. `s3://` not `s3:/`) and ensure the value is non-empty.
Example fix
// before credentials_url = "creds.json" // after credentials_url = "/etc/risingwave/pulsar/creds.json"
Defensive patterns
Strategy: validation
Validate before calling
function validateCredentialsUrl(v) {
if (!v) throw new Error('credentials_url is empty');
if (v.startsWith('/')) return; // absolute path ok
try { const u = new URL(v); if (!['file:', 's3:'].includes(u.protocol)) throw new Error('bad scheme'); }
catch { throw new Error(`credentials_url must be file://, s3://, or an absolute path, got: ${v}`); }
}
validateCredentialsUrl(oauth.credentials_url); Type guard
const isAbsolutePath = (v) => typeof v === 'string' && v.startsWith('/'); Try / catch
try { await createPulsarSource(cfg); } catch (e) { if (String(e).includes('credentials_url must be a valid URL')) throw new Error('Fix credentials_url: use file:///abs/path, s3://bucket/key, or an absolute path'); throw e; } Prevention
- Always use absolute paths or file:///s3:// URLs in credentials_url.
- Never rely on relative paths; the server's working directory is not yours.
- Add config linting that rejects credentials_url values without a known prefix.
When it happens
Trigger: Setting `oauth.credentials_url` to a relative path like `creds.json`, an empty string, or a malformed URL (e.g. `s3:/bucket/file` missing a slash) while configuring a Pulsar source/sink with OAuth authentication.
Common situations: Using a relative path in config because it works locally but the process runs from a different working directory; typos in the URL scheme; copying credentials_url from another system with different path conventions.
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
- credentials file does not exist: {}
- invalid credentials_url scheme '{}', only file://, s3://, an
- The domain only can be specified as 'persistent' or 'non-per
- failed to parse meta address `{1}`: {0}
- path scheme `{scheme}` is not supported
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/e68d1bc363476b10.
Report an issue: GitHub.