risingwavelabs/risingwave · error · PsqlError

Failed to start a new session

Error message

Failed to start a new session: {0}

What it means

pgwire wraps any error that occurs while establishing a new client session (startup/authentication phase) into PsqlError::StartupError with this display message. The boxed source error carries the actual cause. It is thrown by the pgwire session bootstrap path before query handling begins.

Solutions

  1. Read the #[source] BoxedError of PsqlError::StartupError for the concrete root cause.
  2. Check client connection parameters (database name, user, sslmode, protocol version).
  3. Verify the frontend/query engine service is healthy and reachable from pgwire.
  4. Capture server-side logs at session start time to see the original error before wrapping.

Example fix

// before: unwrapping loses the cause
let _ = session.startup(params).unwrap();
// after: downcast to PsqlError and inspect the source
match result {
    Err(e) => { let src = e.source().map(|s| s.to_string()); log::error!("startup failed: {e}, source: {src:?}"); }
    Ok(s) => s.run().await,
}
Defensive patterns

Strategy: try-catch

Validate before calling

// validate startup params before connecting
if database.is_empty() || user.is_empty() { return Err("database and user are required"); }
let reachable = tokio::net::TcpStream::connect(addr).await.is_ok();

Type guard

fn is_startup_error(e: &PsqlError) -> bool { matches!(e, PsqlError::StartupError(_)) }

Try / catch

match conn.start().await {
    Err(e @ PsqlError::StartupError(src)) => { log::error!("startup: {e} (source: {src})"); retry_with_fixed_params(); }
    other => other,
}

Prevention

When it happens

Trigger: Any failure during the PostgreSQL startup packet handling in pgwire: TLS negotiation failure, invalid startup parameters, database/user resolution errors, or an underlying frontend/rw error raised before the session loop starts.

Common situations: Client connects with unsupported sslmode or protocol version; unknown database name at startup; frontend service unavailable when the session is created; corrupted or hostile startup messages.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/dfb78adb7a0d6ddb. Report an issue: GitHub.

Appendix: source

Thrown at src/utils/pgwire/src/error.rs:27

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fmt;
use std::io::Error as IoError;

use risingwave_common::error::code::PostgresErrorCode;
use thiserror::Error;

use crate::pg_server::BoxedError;
pub type PsqlResult<T> = std::result::Result<T, PsqlError>;

/// Error type used in pgwire crates.
#[derive(Error, Debug)]
pub enum PsqlError {
    #[error("Failed to start a new session: {0}")]
    StartupError(
        #[source]
        #[backtrace]
        BoxedError,
    ),

    #[error("Invalid password")]
    PasswordError,

    #[error("Protocol violation: {0}")]
    ProtocolError(
        #[source]
        #[backtrace]
        ProtocolViolationError,
    ),

    #[error("Failed to run the query: {0}")]
    SimpleQueryError(

View on GitHub (pinned to 6469eb736d)