risingwavelabs/risingwave · error · anyhow::Error
Invalid header format
Error message
Invalid header format: {} What it means
The `headers()` parser splits `catalog.header` on ';' then each pair on '=' and requires both a key and a value. A segment that does not yield both (e.g. empty segment or no '=') bails with `Invalid header format` showing the offending pair.
Solutions
- Format each header as `key=value`, separated by ';': e.g. `catalog.header = 'X-Client=wave;Authorization=Bearer xyz'`.
- Remove trailing/leading semicolons and empty segments.
- Ensure every pair contains '='; omit headers you cannot supply a value for.
Example fix
// before catalog.header = 'Authorization=Bearer abc;' // after catalog.header = 'Authorization=Bearer abc'
Defensive patterns
Strategy: validation
Validate before calling
function validateHeaderStr(h) {
if (h === '') return;
for (const pair of h.split(';')) {
if (pair.length === 0 || !pair.includes('=')) {
throw new Error(`Invalid header format: ${pair}`);
}
}
} Type guard
const isValidHeaderStr = (h) => h.split(';').every(p => p.includes('=')); Try / catch
catch (e) { if (String(e).startsWith('Invalid header format')) { /* echo the bad pair and show key=value;key2=value2 syntax */ } else { throw e; } } Prevention
- Always use key=value pairs joined by ';', never a trailing semicolon.
- Validate with a regex like /^[^=;]+=[^=;]*(;[^=;]+=[^=;]*)*$/ before submitting.
- Build the header string programmatically from a map rather than hand-editing.
When it happens
Trigger: `catalog.header` containing an empty segment (double ';' or trailing ';'), or a token without '=' such as 'Authorization' with no value.
Common situations: Trailing semicolons after the last header; pasting a single header line without 'key=value'; whitespace-only segments.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- adlsgen2.authority_host does not parse as a URL
- adlsgen2.authority_host must not contain a path component
- adlsgen2.authority_host must not contain a query or fragment
- adlsgen2.authority_host must not contain userinfo
- adlsgen2.authority_host must use the https scheme, got
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/dd7799bb06eb9196.
Report an issue: GitHub.
Appendix: source
Thrown at src/connector/src/connector_common/iceberg/mod.rs:586
let user_agent = match Deployment::current() {
Deployment::Ci => "RisingWave(CI)".to_owned(),
Deployment::Cloud => "RisingWave(Cloud)".to_owned(),
Deployment::Other => "RisingWave(OSS)".to_owned(),
};
if self.vended_credentials() {
headers.insert(
"X-Iceberg-Access-Delegation".to_owned(),
"vended-credentials".to_owned(),
);
}
headers.insert("User-Agent".to_owned(), user_agent);
if let Some(header) = &self.catalog_header {
for pair in header.split(';') {
let mut parts = pair.split('=');
if let (Some(key), Some(value)) = (parts.next(), parts.next()) {
headers.insert(key.to_owned(), value.to_owned());
} else {
bail!("Invalid header format: {}", pair);
}
}
}
Ok(headers)
}
pub fn enable_config_load(&self) -> bool {
// If the env var is set to true, we disable the default config load. (Cloud environment)
if env_var_is_true(DISABLE_DEFAULT_CREDENTIAL) {
if matches!(self.enable_config_load, Some(true)) {
tracing::warn!(
"`enable_config_load` can't be enabled in SaaS environment, the behavior might be unexpected"
);
}
return false;
}
self.enable_config_load.unwrap_or(false)
}View on GitHub (pinned to 6469eb736d)