{"record":{"id":"fac01202af65375e","repo":"Pumpkin-MC/Pumpkin","slug":"invalid-ed25519-public-key","errorCode":null,"errorMessage":"Invalid Ed25519 public key","messagePattern":"Invalid Ed25519 public key","errorType":"error_code","errorClass":"VineError","httpStatus":null,"severity":"error","filePath":"crates/pumpkin/src/net/proxy/vine.rs","lineNumber":32,"sourceCode":"use sha2::{Digest, Sha256};\nuse thiserror::Error;\nuse tracing::debug;\n\nuse crate::net::{GameProfile, java::pending::PendingConnection};\n\npub const VINE_PLAYER_INFO_CHANNEL: &str = \"vine:player_info\";\npub const VINE_FORWARDING_VERSION: i32 = 1;\npub const MAX_TIMESTAMP_DRIFT_SECS: i64 = 30;\n\n#[derive(Error, Debug)]\npub enum VineError {\n    #[error(\"No response data received\")]\n    NoData,\n    #[error(\"Vine response data too short (minimum 89 bytes)\")]\n    DataTooShort,\n    #[error(\"No public key or secret configured for Vine proxy\")]\n    MissingKeyConfig,\n    #[error(\"Invalid Ed25519 public key\")]\n    InvalidPublicKey,\n    #[error(\"Failed to verify Ed25519 signature\")]\n    InvalidSignature,\n    #[error(\"Failed to read forward version\")]\n    FailedReadForwardVersion,\n    #[error(\"Unsupported forwarding version {0}. Expected {1}\")]\n    UnsupportedForwardVersion(i32, i32),\n    #[error(\"Vine timestamp expired or desynchronized: skew of {0}s exceeds limit of {1}s\")]\n    TimestampExpired(i64, i64),\n    #[error(\"Vine challenge nonce mismatch\")]\n    ChallengeMismatch,\n    #[error(\"Missing expected challenge from pending connection\")]\n    MissingChallenge,\n    #[error(\"Failed to read address\")]\n    FailedReadAddress,\n    #[error(\"Failed to parse address\")]\n    FailedParseAddress,\n    #[error(\"Failed to read game profile name\")]","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin/src/net/proxy/vine.rs#L14-L50","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\npublic_key = \"0x1FC8F9E2...\" // wrong: 0x prefix / not 64 hex chars\n// after\npublic_key = \"1fc8f9e2a4b7c3d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d\"","handlingStrategy":"validation","validationCode":"fn public_key_is_well_formed(hex_str: &str) -> bool {\n    match hex::decode(hex_str.trim()) {\n        Ok(bytes) => bytes.len() == 32,\n        Err(_) => false,\n    }\n}\n// verify before writing the key into the config","typeGuard":null,"tryCatchPattern":"match get_verifying_key(&config) {\n    Err(VineError::InvalidPublicKey) => {\n        eprintln!(\"vine.public_key must be 64 hex chars (32-byte Ed25519 key), got: {:?}\", config.public_key);\n        return;\n    }\n    other => other?,\n}","preventionTips":["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"],"tags":["configuration","crypto","ed25519","minecraft"],"backgroundTag":"invalid-config-value","analyzedSha":"8d4639e25a57c15e47448ec327c780d41bbf2356","analyzedAt":"2026-09-09T15:32:22.916Z","contentChangedAt":"2026-09-09T15:32:22.916Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}