Pumpkin-MC/Pumpkin · error · VelocityError

Failed to read forward version

Error message

Failed to read forward version

What it means

VelocityError sentinel while parsing the modern forwarding payload: the first byte(s) of the forwarded data, which encode the forwarding protocol version, could not be read. Fires when the Velocity proxy response is truncated before the version field — usually a proxy/server version mismatch or a non-Velocity client hitting the forwarding check.

Solutions

  1. Reject the connection
  2. Verify the proxy sends complete velocity:player_info payloads
  3. Log the short read at debug level
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/pumpkin/src/net/proxy/velocity.rs:35 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of Pumpkin-MC/Pumpkin@8d4639e25a (2026-09-09). Data as JSON: /api/errors/95c0d12ea438d8da. Report an issue: GitHub.

Appendix: source

Thrown at crates/pumpkin/src/net/proxy/velocity.rs:35

    net::{IpAddr, SocketAddr},
};
use thiserror::Error;
use tracing::debug;

use crate::net::{GameProfile, java::pending::PendingConnection};

type HmacSha256 = Hmac<Sha256>;

const MAX_SUPPORTED_FORWARDING_VERSION: u8 = 4;
const PLAYER_INFO_CHANNEL: &str = "velocity:player_info";

#[derive(Error, Debug)]
pub enum VelocityError {
    #[error("No response data received")]
    NoData,
    #[error("Unable to verify player details")]
    FailedVerifyIntegrity,
    #[error("Failed to read forward version")]
    FailedReadForwardVersion,
    #[error("Unsupported forwarding version {0}. Maximum supported version is {1}")]
    UnsupportedForwardVersion(u8, u8),
    #[error("Failed to read address")]
    FailedReadAddress,
    #[error("Failed to parse address")]
    FailedParseAddress,
    #[error("Failed to read game profile name")]
    FailedReadProfileName,
    #[error("Failed to read game profile UUID")]
    FailedReadProfileUUID,
    #[error("Failed to read game profile properties")]
    FailedReadProfileProperties,
}

pub async fn velocity_login(connection: &mut PendingConnection) {
    // TODO: Validate the packet transaction id from the plugin response with this
    let velocity_message_id: i32 = rand::rng().random();

View on GitHub (pinned to 8d4639e25a)