vectordotdev/vector · error

Failed to build reflection service

Error message

Failed to build reflection service

What it means

When the Vector gRPC API server starts, it configures a tonic gRPC server reflection service from the embedded observability and health file descriptor sets and panics if `Builder::build()` fails. Reflection fails to build only when the encoded descriptor sets are invalid or empty, so this panic points to a build/codegen problem with the embedded protobuf descriptors, not runtime conditions.

Solutions

  1. Rebuild from clean (`cargo clean`) so `protoc`/tonic codegen regenerates the FILE_DESCRIPTOR_SET constants
  2. Verify tonic, tonic-reflection, and tonic-health versions are mutually compatible in Cargo.lock
  3. Confirm the build script that emits FILE_DESCRIPTOR_SET runs and the file descriptor set is non-empty
  4. Pin known-good tonic/tonic-reflection versions if a recent dependency bump introduced the failure

Example fix

// before (incompatible tonic-reflection after cargo update)
.build().expect("Failed to build reflection service");
// after
$ cargo update -p tonic-reflection --precise 0.x.y  # match workspace tonic
$ cargo clean && cargo build
Defensive patterns

Strategy: retry

Validate before calling

assert!(!crate::proto::observability::FILE_DESCRIPTOR_SET.is_empty());
assert!(!tonic_health::pb::FILE_DESCRIPTOR_SET.is_empty());

Try / catch

let reflection = tonic_reflection::server::Builder::configure()
    .register_encoded_file_descriptor_set(crate::proto::observability::FILE_DESCRIPTOR_SET)
    .build()
    .map_err(|e| { error!("reflection service build failed: {e}"); e })?;

Prevention

When it happens

Trigger: Calling `start` for the gRPC API when `tonic_reflection::server::Builder::configure().build()` returns Err — corrupted or empty `FILE_DESCRIPTOR_SET` constants (bad tonic/protoc codegen output).

Common situations: Mismatched tonic/tonic-reflection/protoc versions generating empty or malformed descriptor sets; regenerating protos with a broken build script; unusual feature-flag combinations excluding the descriptor.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/637a804087fbe825. Report an issue: GitHub.

Appendix: source

Thrown at src/api/grpc_server.rs:91

        let std_listener = listener
            .into_std()
            .map_err(|e| crate::Error::from(format!("Failed to convert TCP listener: {e}")))?;
        std_listener.set_nonblocking(true).map_err(|e| {
            crate::Error::from(format!("Failed to set TCP listener non-blocking: {e}"))
        })?;

        let router_serving = Arc::clone(&serving);

        // Spawn the server with the already-bound listener
        crate::spawn_in_current_span(async move {
            // Build reflection service for tools like grpcurl
            let reflection_service = tonic_reflection::server::Builder::configure()
                .register_encoded_file_descriptor_set(
                    crate::proto::observability::FILE_DESCRIPTOR_SET,
                )
                .register_encoded_file_descriptor_set(tonic_health::pb::FILE_DESCRIPTOR_SET)
                .build()
                .expect("Failed to build reflection service");

            // Build the tonic router (gRPC services) and merge with the HTTP router
            // so both protocols share the same port. `accept_http1(true)` lets plain
            // HTTP/1.1 requests reach the merged axum routes.
            let router = TonicServer::builder()
                .accept_http1(true)
                .add_service(health_service)
                .add_service(ObservabilityServer::new(service))
                .add_service(reflection_service)
                .into_router()
                .merge(http_router(router_serving));

            let result = hyper::Server::from_tcp(std_listener)
                .expect("Failed to build HTTP server from TCP listener")
                .serve(router.into_make_service())
                .with_graceful_shutdown(async {
                    rx.await.ok();
                    info!("GRPC API server shutting down.");

View on GitHub (pinned to bdb87aeaa4)