Pumpkin-MC/Pumpkin · error · VineError

Unsupported forwarding version

Error message

Unsupported forwarding version {0}. Expected {1}

What it means

VineError::UnsupportedForwardVersion is raised when the decoded forwarding version in the Vine payload differs from VINE_FORWARDING_VERSION (1) supported by this server (vine.rs:173-178). The signature was valid, so the proxy is authentic but speaks a different protocol revision. The error carries the received and expected versions for diagnosis.

Solutions

  1. Upgrade the server (or proxy) so both sides implement the same Vine forwarding version (currently 1)
  2. Pin both proxy and server to compatible release versions
  3. If a fork sends a different version, align it with the standard VINE_FORWARDING_VERSION = 1

Example fix

// before (proxy side)
const FORWARDING_VERSION: i32 = 2; // newer than server supports
// after
const FORWARDING_VERSION: i32 = 1; // matches server's VINE_FORWARDING_VERSION
Defensive patterns

Strategy: try-catch

Validate before calling

fn check_version_compatibility(payload_version: i32, supported: i32) -> bool {
    payload_version == supported // Vine has no backward compatibility window; exact match required
}

Try / catch

match receive_vine_plugin_response(port, &config, response, challenge) {
    Err(VineError::UnsupportedForwardVersion(got, expected)) => {
        tracing::error!("Proxy speaks Vine forwarding v{}, server needs v{} — upgrade the older side", got, expected);
        disconnect(DisconnectReason::UnsupportedForwardingVersion);
    }
    result => result?,
}

Prevention

When it happens

Trigger: receive_vine_plugin_response reads version != 1 from the payload: the proxy was built for a newer/older Vine forwarding spec, or a custom implementation hardcodes a different version constant.

Common situations: The proxy was upgraded to a newer Vine protocol before the server, or vice versa; a forked proxy implementation uses its own version number; experimental/nightly builds of either side diverged.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

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")]
    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,
}

View on GitHub (pinned to 8d4639e25a)