risingwavelabs/risingwave · error · io::Error
InvalidInput
InvalidInput
Error message
Input end error
What it means
This error is thrown when parsing the frontend startup message payload: `FeStartupMessage::build_with_payload` first decodes the payload as UTF-8, and if the bytes are not valid UTF-8, the `Utf8Error` is wrapped with the 'Input end error' context and an `ErrorKind::InvalidInput`. The PostgreSQL wire protocol requires startup parameters to be UTF-8 encoded null-terminated strings, so undecodable bytes are rejected before the config map is built.
Source
Thrown at src/utils/pgwire/src/pg_message.rs:81
#[derive(Debug)]
pub enum ServerThrottleReason {
TooLargeMessage,
TooManyMemoryUsage,
}
#[derive(Debug)]
pub struct FeStartupMessage {
pub config: HashMap<String, String>,
}
impl FeStartupMessage {
pub fn build_with_payload(payload: &[u8]) -> Result<Self> {
let config = match std::str::from_utf8(payload) {
Ok(v) => Ok(v.strip_suffix('\0').unwrap_or(v)),
Err(err) => Err(Error::new(
ErrorKind::InvalidInput,
anyhow!(err).context("Input end error"),
)),
}?;
let mut map = HashMap::new();
let config: Vec<&str> = config.split_terminator('\0').collect();
if config.len() % 2 == 1 {
return Err(Error::new(
ErrorKind::InvalidInput,
"Invalid input config: odd number of config pairs",
));
}
config.chunks(2).for_each(|chunk| {
map.insert(chunk[0].to_owned(), chunk[1].to_owned());
});
Ok(FeStartupMessage { config: map })
}
}
/// Query message contains the string sql.View on GitHub (pinned to 6469eb736d)
Solutions
- Configure the client/driver to use UTF-8 encoding for connection parameters (e.g. `client_encoding=UTF8`)
- Check that no proxy or middleware re-encodes the startup packet bytes
- Ensure database/user/application_name values contain only characters representable in UTF-8 as sent by the driver
- If writing a custom client, encode all startup-payload strings as UTF-8 with NUL terminators
Example fix
// before (custom client, local codepage) payload.write_all(username.encode(Encoding::GBK).as_slice()); // after payload.write_all(username.as_bytes()); // Rust str is UTF-8
Defensive patterns
Strategy: try-catch
Validate before calling
fn is_valid_utf8_payload(payload: &[u8]) -> bool {
std::str::from_utf8(payload).is_ok()
} Try / catch
match std::str::from_utf8(payload) {
Ok(s) => s,
Err(e) => {
// log the byte offset: e.valid_up_to(), reject connection
return Err(...);
}
} Prevention
- Always configure drivers to UTF-8 client encoding
- Avoid non-ASCII values in connection parameters unless the driver is UTF-8 safe
- Audit proxies/protocol translators for byte-rewriting behavior
When it happens
Trigger: A client sends a startup packet whose payload contains bytes that fail `std::str::from_utf8` — e.g. a driver sending strings in a non-UTF-8 legacy encoding (Latin-1, GBK) in parameters like `user`, `database`, or `application_name`.
Common situations: Legacy clients or misconfigured JDBC/ODBC drivers with non-UTF-8 client encoding; passwords or database names containing non-ASCII characters encoded in a local codepage; corrupted or truncated TCP payloads from a faulty proxy.
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
- decode utf8 error: {0}
- invalid UTF-8 in `{key}` header
- Invalid UTF8 value encoding: {0}
- Fail to convert version_hint from utf8 to string: {}
- unsupported encoding for Debezium
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/07b4412a8ce9ca6a.
Report an issue: GitHub.