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
- Re-copy the 64-character hex Ed25519 public key exactly as the proxy reports it
- Check the decoded key is 32 bytes (64 hex chars) with no 0x prefix, whitespace inside, or base64 content
- 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
- Store the key as lowercase hex, exactly 64 characters, no 0x prefix or quotes inside the value
- Copy keys programmatically (config management) rather than by hand to avoid truncation
- Never paste the proxy's private key into public_key; use its public key output
- Validate the key parses once at startup to catch bad values before players connect
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
- No public key or secret configured for Vine proxy
- Failed to verify Ed25519 signature
- JWT chain validation failed
- The validated username is invalid
- Could not parse UUID from validated token
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)