influxdata/influxdb · error · Error
Handshake failed
Error message
Handshake failed: {0} What it means
Error variant `HandshakeFailed(String)` of the influxdb_iox_client Flight client's Error enum, thrown when the Arrow Flight handshake with the IOx server fails. The handshake is the first gRPC/tonic call made when connecting, so this wraps any transport, protocol, or authentication failure reported during `handshake()`. The inner String carries the underlying tonic/Flight error message.
Solutions
- Check that the IOx server is running and the configured address/port is correct
- Verify TLS configuration (certificates, CA bundle) matches between client and server
- Validate credentials/bearer token are present and not expired
- Retry with backoff — transient network blips during startup commonly fail the handshake
- Inspect the embedded message for the underlying tonic status and match it to server-side logs
Example fix
// before
let client = FlightClient::new(channel).await?;
// after
let client = match FlightClient::new(channel).await {
Ok(c) => c,
Err(e) => {
if let Some(status) = e.tonic_status() {
eprintln!("handshake rejected: {}", status);
}
return Err(e);
}
}; Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: verify the server accepts gRPC connections // e.g. `nc -zv host 443` or a lightweight health/rpc call before creating the client
Type guard
fn is_handshake_failed(e: &Error) -> bool {
matches!(e, Error::HandshakeFailed(_))
} Try / catch
match client.connect().await {
Err(Error::HandshakeFailed(msg)) => {
eprintln!("handshake failed: {msg}; check server addr/TLS/token");
// retry with backoff or surface config error
}
Err(e) => return Err(e),
Ok(c) => c,
} Prevention
- Add a startup health check against the Flight endpoint before queries
- Keep bearer tokens fresh and loaded from a validated source
- Match arrow-flight/tonic versions between client and server
- Use exponential backoff for transient handshake failures
When it happens
Trigger: Calling the Flight client's connect/query path when the server's `handshake()` future resolves to an error: server unreachable or restarted mid-handshake, TLS/transport error, server rejecting credentials during handshake, or an incompatible Flight protocol version.
Common situations: IOx server down or listening on a different port than configured; TLS certificate mismatch; expired or invalid bearer token rejected at handshake; version skew between client and server Arrow Flight implementations.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Deadline expired before operation could complete
- Unknown server error
- {0}
- An unexpected error occurred in the client library
- client disconnected
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/587671d2b3c01181.
Report an issue: GitHub.
Appendix: source
Thrown at core/influxdb_iox_client/src/client/flight/mod.rs:60
#[error(transparent)]
ArrowError(#[from] arrow::error::ArrowError),
/// An error involving an Arrow Flight operation occurred.
#[error(transparent)]
ArrowFlightError(#[from] FlightError),
/// The data contained invalid Flatbuffers.
#[error("Invalid Flatbuffer: `{0}`")]
InvalidFlatbuffer(String),
/// The message header said it was a dictionary batch, but interpreting the
/// message as a dictionary batch returned `None`. Indicates malformed
/// Flight data from the server.
#[error("Message with header of type dictionary batch could not return a dictionary batch")]
CouldNotGetDictionaryBatch,
/// Arrow Flight handshake failed.
#[error("Handshake failed: {0}")]
HandshakeFailed(String),
/// Serializing the protobuf structs into bytes failed.
#[error(transparent)]
Serialization(#[from] prost::EncodeError),
/// Deserializing the protobuf structs from bytes failed.
#[error(transparent)]
Deserialization(#[from] prost::DecodeError),
/// Unknown IPC message type.
#[error("Unknown IPC message type: {0:?}")]
UnknownMessageType(ipc::MessageHeader),
/// Unexpected schema change.
#[error("Unexpected schema change")]
UnexpectedSchemaChange,
}View on GitHub (pinned to 06200ef96b)