Pumpkin-MC/Pumpkin · error · VineError

Vine response data too short (minimum 89 bytes)

Error message

Vine response data too short (minimum 89 bytes)

What it means

VineError::DataTooShort is raised during the Vine modern forwarding handshake when the login plugin response payload received from the proxy is smaller than the minimum 89 bytes (64-byte Ed25519 signature + VarInt version + 8-byte timestamp + 16-byte challenge nonce). The server refuses to parse the packet because required fields would be missing. It is thrown by receive_vine_plugin_response in crates/pumpkin/src/net/proxy/vine.rs:154-156 and also when the timestamp or nonce slices cannot be read (lines 184, 200).

Solutions

  1. Verify the proxy (e.g. Velocity or the Vine-compatible proxy) has Vine/modern forwarding ENABLED and is sending the full signed payload
  2. Confirm the proxy and Pumpkin server use the same Vine forwarding version and protocol implementation
  3. Ensure clients cannot connect directly to the backend port; only the proxy should reach it
  4. Capture the raw login plugin response and check its length to see who is sending the malformed packet
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_vine_response(data: &[u8]) -> bool {
    const MIN: usize = 64 + 1 + 8 + 16; // 89 bytes
    data.len() >= MIN
}
// call before handing SLoginPluginResponse data to the verifier

Type guard

fn has_full_vine_payload(data: &Option<Box<[u8]>>) -> bool {
    matches!(data, Some(d) if d.len() >= 64 + 1 + 8 + 16)
}

Try / catch

match receive_vine_plugin_response(port, &config, response, challenge) {
    Err(VineError::DataTooShort) => {
        tracing::warn!("Vine response truncated ({} bytes); check proxy forwarding config", response.data.map_or(0, |d| d.len()));
        disconnect(DisconnectReason::InvalidForwarding);
    }
    result => result?,
}

Prevention

When it happens

Trigger: A proxy responds on the vine:player_info channel with a payload shorter than 89 bytes: the proxy sends an empty/truncated payload, a proxy not implementing Vine forwarding echoes back wrong data, or a malicious/broken client forges a minimal login plugin response.

Common situations: The upstream proxy has Vine forwarding disabled or only legacy (BungeeCord) forwarding enabled; the proxy and server run incompatible Vine protocol versions; a client connects directly to the backend bypassing the proxy and fakes the plugin response channel.

Related errors


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

Appendix: source

Thrown at crates/pumpkin/src/net/proxy/vine.rs:28

use pumpkin_protocol::{
    Property, java::client::login::CLoginPluginRequest, java::server::login::SLoginPluginResponse,
    ser::NetworkReadExt,
};
use sha2::{Digest, Sha256};
use thiserror::Error;
use tracing::debug;

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

pub const VINE_PLAYER_INFO_CHANNEL: &str = "vine:player_info";
pub const VINE_FORWARDING_VERSION: i32 = 1;
pub const MAX_TIMESTAMP_DRIFT_SECS: i64 = 30;

#[derive(Error, Debug)]
pub enum VineError {
    #[error("No response data received")]
    NoData,
    #[error("Vine response data too short (minimum 89 bytes)")]
    DataTooShort,
    #[error("No public key or secret configured for Vine proxy")]
    MissingKeyConfig,
    #[error("Invalid Ed25519 public key")]
    InvalidPublicKey,
    #[error("Failed to verify Ed25519 signature")]
    InvalidSignature,
    #[error("Failed to read forward version")]
    FailedReadForwardVersion,
    #[error("Unsupported forwarding version {0}. Expected {1}")]
    UnsupportedForwardVersion(i32, i32),
    #[error("Vine timestamp expired or desynchronized: skew of {0}s exceeds limit of {1}s")]
    TimestampExpired(i64, i64),
    #[error("Vine challenge nonce mismatch")]
    ChallengeMismatch,
    #[error("Missing expected challenge from pending connection")]
    MissingChallenge,
    #[error("Failed to read address")]

View on GitHub (pinned to 8d4639e25a)