hasura/graphql-engine · critical · StartupError

could not read the auth config - {0}

Error message

could not read the auth config - {0}

What it means

Variant StartupError::ReadAuth wrapping the underlying anyhow error raised while reading or parsing the auth configuration. It surfaces as 'could not read the auth config - <cause>' during engine startup and is classified as user-visible (ErrorVisibility::User), i.e. it's the operator's responsibility, not an internal bug.

Source

Thrown at v3/crates/engine/src/types.rs:25

use tracing_util::{ErrorVisibility, TraceableError};

#[derive(Clone)] // Cheap to clone as heavy fields are wrapped in `Arc`
pub struct EngineState {
    pub expose_internal_errors: ExposeInternalErrors,
    pub http_context: HttpContext,
    pub graphql_state: Arc<gql::schema::Schema<GDS>>,
    pub resolved_metadata: Arc<metadata_resolve::Metadata>,
    pub jsonapi_catalog: Arc<jsonapi::Catalog>,
    pub auth_config: Arc<ResolvedAuthConfig>,
    pub graphql_websocket_server:
        Arc<graphql_ws::WebSocketServer<graphql_ws::NoOpWebSocketMetrics>>,
    pub auth_mode_header: String,
}

#[derive(thiserror::Error, Debug)]
#[allow(clippy::enum_variant_names)]
pub enum StartupError {
    #[error("could not read the auth config - {0}")]
    ReadAuth(anyhow::Error),
    #[error("failed to build engine state - {0}")]
    ReadSchema(anyhow::Error),
}

impl TraceableError for StartupError {
    fn visibility(&self) -> tracing_util::ErrorVisibility {
        ErrorVisibility::User
    }
}

/// The type of request being made to the engine
pub enum RequestType {
    Http,
    WebSocket,
}

impl RequestType {

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Check the wrapped cause after the dash — it names the exact read/parse failure
  2. Validate the auth config JSON with jq or a JSON schema before deploying
  3. Ensure the file path in your server config points to the intended auth config
  4. After upgrading the engine, re-check the expected auth config format

Example fix

// before
{"authn": {"authentication": {"jwt": {"issuer": ...}}}}  // malformed/truncated

// after
# validate first
jq . auth_config.json && engine --authn-config-path ./auth_config.json
Defensive patterns

Strategy: validation

Validate before calling

let raw = std::fs::read_to_string(&path).map_err(anyhow::Error::from)?;
serde_json::from_str::<AuthConfig>(&raw)
    .map_err(|e| StartupError::ReadAuth(e.into()))?;

Type guard

fn is_read_auth(e: &StartupError) -> bool { matches!(e, StartupError::ReadAuth(_)) }

Try / catch

Match StartupError::ReadAuth(err) at startup and print err (the wrapped cause) plus the configured path; exit non-zero.

Prevention

When it happens

Trigger: Engine state construction (build engine state) when reading the authn config file fails (missing/unreadable file) or when parsing its contents (e.g. malformed JSON/JWKS structure) produces an error wrapped into this variant.

Common situations: Missing auth config in deployments, malformed JSON after templating/envsubst, wrong file referenced by config, changed auth config schema between engine versions.

Related errors


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