Pumpkin-MC/Pumpkin · error · VineError

No public key or secret configured for Vine proxy

Error message

No public key or secret configured for Vine proxy

What it means

VineError::MissingKeyConfig is returned by get_verifying_key (crates/pumpkin/src/net/proxy/vine.rs:83-108) when Vine forwarding is enabled but both the public_key and secret fields in the VineConfig are empty or whitespace-only. The server has no key material to verify the proxy's Ed25519 signature, so it cannot trust the forwarded player data. Configuration is rejected before any signature verification is attempted.

Solutions

  1. Set either vine public_key (hex-encoded 32-byte Ed25519 public key from the proxy) or vine secret (shared secret) in the server's VineConfig
  2. Copy the public key exactly as printed by the proxy, without extra whitespace
  3. Restart the server after editing the config so the new VineConfig is loaded

Example fix

// before (config)
[vine]
enabled = true
public_key = ""
secret = ""
// after
[vine]
enabled = true
public_key = "1fc8f9e2a4b7..." # hex Ed25519 public key from the proxy
Defensive patterns

Strategy: validation

Validate before calling

fn validate_vine_config(config: &VineConfig) -> Result<(), String> {
    if config.public_key.trim().is_empty() && config.secret.trim().is_empty() {
        return Err("Set either vine.public_key or vine.secret when Vine forwarding is enabled".into());
    }
    Ok(())
}
// run at startup before accepting connections

Type guard

fn has_key_material(config: &VineConfig) -> bool {
    !config.public_key.trim().is_empty() || !config.secret.trim().is_empty()
}

Try / catch

match get_verifying_key(&config) {
    Err(VineError::MissingKeyConfig) => {
        eprintln!("Vine forwarding enabled but no public_key/secret set; refusing logins");
        return;
    }
    other => other?,
}

Prevention

When it happens

Trigger: receive_vine_plugin_response processes a valid Vine response and calls get_verifying_key, but config.public_key and config.secret are both empty/blank strings in the server's network proxy configuration.

Common situations: The operator enabled Vine forwarding in the config but forgot to copy the proxy's public key or shared secret; the config key was misspelled or left as the default empty placeholder; the config file was reset or regenerated without preserving the key fields.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

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

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

View on GitHub (pinned to 8d4639e25a)