getzola/zola · info

Could not build error response

Error message

Could not build error response

What it means

error_injection_middleware constructs an HTML error page response for build errors with Response::builder().body(...).expect("Could not build error response"). The builder only fails if a header value or body conversion is invalid; with the current static headers this is an invariant panic path in the dev server.

Source

Thrown at src/cmd/serve.rs:340

            r#"<div style="all:revert;position:fixed;display:flex;align-items:center;justify-content:center;background-color:rgb(0,0,0,0.5);top:0;right:0;bottom:0;left:0;"><div style="background-color:white;padding:0.5rem;border-radius:0.375rem;filter:drop-shadow(0,25px,25px,rgb(0,0,0/0.15));overflow-x:auto;"><p style="font-weight:700;color:black;font-size:1.25rem;margin:0;margin-bottom:0.5rem;">Zola Build Error:</p><pre style="padding:0.5rem;margin:0;border-radius:0.375rem;background-color:#363636;color:#CE4A2F;font-weight:700;">{error_str}</pre></div></div>"#
        );

        if is_html {
            // Inject error dialog into existing HTML response
            let mut new_bytes = bytes;
            new_bytes.extend(html_error.as_bytes());
            return Response::from_parts(parts, Body::from(new_bytes));
        } else if is_not_found {
            // Return a full HTML page with the error dialog for 404s
            // Include livereload.js so the page can receive reload messages when the error is fixed
            let html_page = format!(
                r#"<!DOCTYPE html><html><head><title>Zola Build Error</title><script src="/livereload.js"></script></head><body>{html_error}</body></html>"#
            );
            return Response::builder()
                .header(header::CONTENT_TYPE, "text/html")
                .status(StatusCode::OK)
                .body(Body::from(html_page))
                .expect("Could not build error response");
        }
    }

    Response::from_parts(parts, Body::from(bytes))
}

fn in_memory_content(path: &RelativePathBuf, content: &str) -> Response {
    let content_type = match path.extension() {
        Some(ext) => match ext {
            "xml" => "text/xml",
            "json" => "application/json",
            "txt" => "text/plain",
            _ => "text/html",
        },
        None => "text/html",
    };
    Response::builder()
        .header(header::CONTENT_TYPE, content_type)

View on GitHub (pinned to 61d3082821)

Solutions

  1. Use HeaderValue::from_static/from_bytes-checked values for any custom header
  2. Construct the response with Response::new and headers_mut() to avoid the fallible builder
  3. Sanitize/validate dynamic header content before injecting it

Example fix

// before
return Response::builder()
    .header(header::CONTENT_TYPE, "text/html")
    .status(StatusCode::OK)
    .body(Body::from(html_page))
    .expect("Could not build error response");
// after
let mut response = Response::new(Body::from(html_page));
*response.status_mut() = StatusCode::OK;
response.headers_mut().insert(header::CONTENT_TYPE, HeaderValue::from_static("text/html"));
return response;
Defensive patterns

Strategy: fallback

Validate before calling

let html_header = http::HeaderValue::from_str("text/html")
    .expect("static header must be valid");

Try / catch

match Response::builder()
    .header(header::CONTENT_TYPE, "text/html")
    .status(StatusCode::OK)
    .body(Body::from(html_page))
{
    Ok(resp) => resp,
    Err(e) => {
        eprintln!("error page build failed: {}", e);
        StatusCode::INTERNAL_SERVER_ERROR.into_response()
    }
}

Prevention

When it happens

Trigger: `zola serve` with a build error whose injected html_error content causes the response builder to fail — e.g. after modifying the code to add invalid header values; otherwise unreachable with static headers.

Common situations: Customizing the middleware (e.g. adding a content-security-policy header built from dynamic strings) and hitting a hyper HeaderValue parse failure while a rebuild error page is shown.

Related errors


AI-assisted analysis of getzola/zola@61d3082821 (2026-09-03). Data as JSON: /api/errors/3f388927c0ceb5e5. Report an issue: GitHub.