Pumpkin-MC/Pumpkin · error · VineError

Invalid Ed25519 public key

Error message

Invalid Ed25519 public key

What it means

VineError::InvalidPublicKey is raised when the configured public_key string cannot be turned into an Ed25519 verifying key: hex decoding fails, the decoded bytes are not exactly 32 bytes, or ed25519_dalek rejects the key bytes (vine.rs:86-92). The server aborts verification of the Vine forwarding response rather than trusting unauthenticated data.

Solutions

  1. Re-copy the 64-character hex Ed25519 public key exactly as the proxy reports it
  2. Check the decoded key is 32 bytes (64 hex chars) with no 0x prefix, whitespace inside, or base64 content
  3. If using the secret-based derivation instead, clear public_key and set secret so SHA-256 seed derivation is used

Example fix

// before
public_key = "0x1FC8F9E2..." // wrong: 0x prefix / not 64 hex chars
// after
public_key = "1fc8f9e2a4b7c3d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d"
Defensive patterns

Strategy: validation

Validate before calling

fn public_key_is_well_formed(hex_str: &str) -> bool {
    match hex::decode(hex_str.trim()) {
        Ok(bytes) => bytes.len() == 32,
        Err(_) => false,
    }
}
// verify before writing the key into the config

Try / catch

match get_verifying_key(&config) {
    Err(VineError::InvalidPublicKey) => {
        eprintln!("vine.public_key must be 64 hex chars (32-byte Ed25519 key), got: {:?}", config.public_key);
        return;
    }
    other => other?,
}

Prevention

When it happens

Trigger: get_verifying_key is called during a Vine login response and the config.public_key value is not valid hex, decodes to a length other than 32 bytes, or is not a valid Ed25519 point (VerifyingKey::from_bytes fails).

Common situations: Operator pasted a base64 key instead of hex, truncated the key while copying, copied the proxy's private/secret key instead of its public key, or included quotes/'0x' prefixes in the config value.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

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")]
    FailedReadAddress,
    #[error("Failed to parse address")]
    FailedParseAddress,
    #[error("Failed to read game profile name")]

View on GitHub (pinned to 8d4639e25a)