hasura/graphql-engine · critical

could not read metadata

Error message

could not read metadata

What it means

Panic from expect() in the engine's main() when the metadata (OpenDD) JSON file cannot be read from disk. The engine requires the metadata document describing connectors and authentication to start, so an unreadable file aborts startup.

Source

Thrown at v3/crates/engine/bin/engine/main.rs:147

    tracing_util::shutdown_tracer();
}

#[allow(clippy::print_stdout)]
async fn start_engine(server: &ServerOptions) -> Result<(), StartupError> {
    let metadata_resolve_configuration = metadata_resolve::configuration::Configuration {
        unstable_features: resolve_unstable_features(&server.unstable_features),
    };

    let expose_internal_errors = if server.expose_internal_errors {
        ExposeInternalErrors::Expose
    } else {
        ExposeInternalErrors::Censor
    };

    let raw_auth_config =
        std::fs::read_to_string(&server.authn_config_path).expect("could not read auth config");
    let opendd_metadata_json =
        std::fs::read_to_string(&server.metadata_path).expect("could not read metadata");

    let (resolved_metadata, auth_config) = engine::resolve_metadata(
        &opendd_metadata_json,
        &raw_auth_config,
        &metadata_resolve_configuration,
    )
    .map_err(StartupError::ReadSchema)?;

    let state = engine::build_state(
        expose_internal_errors,
        auth_config,
        resolved_metadata,
        server.auth_mode_header.clone(),
        server.ndc_response_size_limit,
    )
    .map_err(StartupError::ReadSchema)?;

    let mut app = get_base_routes(state.clone(), server.request_body_limit);

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Confirm the metadata file exists at the exact path passed to the binary
  2. Regenerate metadata via your build/federation step if it was never produced
  3. Ensure the file is valid UTF-8 text (file <path>, iconv if needed)
  4. Fix permissions or mount the file into the container

Example fix

// before
let opendd_metadata_json =
    std::fs::read_to_string(&server.metadata_path).expect("could not read metadata");

// after
let opendd_metadata_json = std::fs::read_to_string(&server.metadata_path)
    .with_context(|| format!("could not read metadata at {}", server.metadata_path.display()))?;
Defensive patterns

Strategy: validation

Validate before calling

let p = &server.metadata_path;
assert!(p.is_file(), "metadata file missing: {}", p.display());
let bytes = std::fs::read(p)?;
let opendd_metadata_json = String::from_utf8(bytes)?;

Try / catch

Convert the expect() into a Result with context (path + io error kind) so startup surfaces an actionable message.

Prevention

When it happens

Trigger: Starting the engine with a metadata path that does not exist, is unreadable, is a directory, or contains non-UTF8 bytes (read_to_string requires valid UTF-8).

Common situations: Metadata file not generated or not copied into CI/deployment artifacts, path typos in launch scripts, non-UTF8 metadata produced by other tooling, or missing volume mounts.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/c6302b0616d2611c. Report an issue: GitHub.