Pumpkin-MC/Pumpkin · error · TextureError

Invalid URL

Error message

Invalid URL

What it means

PacketError::MissingNullTerminator is raised when an RCON packet's string body is not terminated by the required NUL byte. The RCON protocol requires payload strings to be null-terminated; a missing terminator means the packet is malformed. The codec rejects the packet rather than reading past its bounds.

Solutions

  1. Fix the peer's packet builder to append a NUL byte after each string field.
  2. Validate the last byte of the parsed body is 0 before converting to a string; reject otherwise.
  3. Verify packet length calculations include the null terminator byte.
  4. If parsing external captures, confirm the framing offset is correct so the terminator is within the body slice.

Example fix

// before
let body = std::str::from_utf8(&payload)?; // no terminator check
// after
let body_bytes = &payload[..payload.len().saturating_sub(1)];
if payload.last() != Some(&0) {
    return Err(PacketError::MissingNullTerminator);
}
let body = std::str::from_utf8(body_bytes)?;
Defensive patterns

Strategy: validation

Validate before calling

fn body_is_terminated(payload: &[u8]) -> bool {
    payload.last() == Some(&0)
}

Type guard

fn has_null_terminator(payload: &[u8]) -> bool {
    !payload.is_empty() && *payload.last().unwrap() == 0
}

Try / catch

match rcon_conn.read_packet().await {
    Err(PacketError::MissingNullTerminator) => {
        warn!("malformed RCON packet from peer (missing NUL)");
        // flag peer as non-conformant
    }
    Ok(p) => handle(p),
    Err(e) => warn!("rcon error: {e}"),
}

Prevention

When it happens

Trigger: Parsing a received RCON packet whose body lacks the trailing \0; a peer implementation that forgets to null-terminate strings; a framing offset that makes the terminator land outside the parsed body.

Common situations: Interoperating with third-party/broken RCON clients or servers; off-by-one errors in custom packet builders; corrupted stream data shifting the body boundary.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at crates/pumpkin/src/net/authentication.rs:413

    #[error("Authentication servers are down")]
    FailedResponse,
    #[error("Failed to verify username")]
    UnverifiedUsername,
    #[error("You are banned from Authentication servers")]
    Banned,
    #[error("Texture Error {0}")]
    TextureError(TextureError),
    #[error("You have disallowed actions from Authentication servers")]
    DisallowedAction,
    #[error("Failed to parse JSON into Game Profile")]
    FailedParse,
    #[error("Unknown Status Code {0}")]
    UnknownStatusCode(StatusCode),
}

#[derive(Error, Debug)]
pub enum TextureError {
    #[error("Invalid URL")]
    InvalidURL,
    #[error("Invalid URL scheme for player texture: {0}")]
    DisallowedUrlScheme(String),
    #[error("Invalid URL domain for player texture: {0}")]
    DisallowedUrlDomain(String),
    #[error("Failed to decode base64 player texture: {0}")]
    DecodeError(String),
    #[error("Failed to parse JSON from player texture: {0}")]
    JSONError(String),
}

#[cfg(test)]
mod tests {
    use super::ProfileTextures;

    // Third-party auth servers (drasl, Blessing Skin, littleskin.cn) don't send
    // `signatureRequired`. The profile must still parse. See issue #301.
    #[test]

View on GitHub (pinned to 8d4639e25a)