EpicGames/lore · error · anyhow::Error

{} {err}

Error message

{} {err}

What it means

build_presign_config converts the content-type policy into a ContentTypeAllowlist via try_from_policy; if the policy is invalid, the allowlist's own error is prefixed with the offending field name and propagated. The server cannot start with a presign content-type policy that references unknown or disallowed fields.

Solutions

  1. Read the prefixed field name in the message to identify which policy entry is invalid.
  2. Fix or remove the offending content type in settings.presign.content_type_policy.
  3. Consult the builtin allowlist policy and model custom entries on its format.
  4. Add a unit test mirroring build_presign_config_rejects_never_allowed_extra_type for your policy.
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: build the allowlist the same way the server does
ContentTypeAllowlist::try_from_policy(&settings.content_type_policy)
    .map_err(|e| anyhow!("{} {e}", presign_content_type_field(e.field())))?;

Try / catch

// Startup validation in the deploy harness
match ContentTypeAllowlist::try_from_policy(&policy) {
    Ok(_) => {},
    Err(e) => eprintln!("bad presign content_type_policy field '{}': {e}", e.field()),
}

Prevention

When it happens

Trigger: PresignSettings.content_type_policy fails ContentTypeAllowlist::try_from_policy — e.g. a content type in an extra-allowed list that is never allowed, or a malformed policy field (the err.field() name appears in the message).

Common situations: Operators add custom content types to the presign allow/deny policy that violate the policy rules; typos in content-type strings; a policy edited after an upgrade tightened validation.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of EpicGames/lore@074eb0b0d1 (2026-09-13). Data as JSON: /api/errors/e81b23b0e0a47cc4. Report an issue: GitHub.

Appendix: source

Thrown at lore-server/src/http/server.rs:225

        anyhow::bail!(
            "presigned_url_hmac_key must be at least {MIN_HMAC_KEY_BYTES} bytes, got {}",
            key_bytes.len()
        );
    }

    let key_id = blake3::hash(&key_bytes).to_hex()[..16].to_string();
    let hmac_key = hmac::Key::new(hmac::HMAC_SHA256, &key_bytes);

    Ok(Some(PresignConfig {
        hmac_key,
        key_id,
        min_ttl_seconds: settings.min_ttl_seconds,
        default_ttl_seconds: settings.default_ttl_seconds,
        max_ttl_seconds: settings.max_ttl_seconds,
        content_type_allowlist: ContentTypeAllowlist::try_from_policy(
            &settings.content_type_policy,
        )
        .map_err(|err| anyhow!("{} {err}", presign_content_type_field(err.field())))?,
    }))
}

impl LoreHttpServer {
    /// Starts a minimal HTTP server that only serves the `/health_check` endpoint.
    ///
    /// Used during maintenance mode so that load balancers and monitoring systems
    /// can still reach the server. Always returns 200 OK (store health checks are
    /// disabled since the server is intentionally in a reduced state).
    pub async fn serve_maintenance(
        host: String,
        port: i32,
        user_agent_filter: Arc<UserAgentFilter>,
        signal: impl Future<Output = ()> + Send + 'static,
    ) -> Result<()> {
        let addr = SocketAddr::from_str(format!("{host}:{port}").as_str())
            .map_err(|err| anyhow!("Failed to start maintenance HTTP server: {err}"))?;
        info!("Starting Lore maintenance HTTP Server: {}", &addr);

View on GitHub (pinned to 074eb0b0d1)