{"record":{"id":"9807af8f64a5955d","repo":"hasura/graphql-engine","slug":"could-not-read-the-auth-config-0","errorCode":null,"errorMessage":"could not read the auth config - {0}","messagePattern":"could not read the auth config - (.+?)","errorType":"exception","errorClass":"StartupError","httpStatus":null,"severity":"critical","filePath":"v3/crates/engine/src/types.rs","lineNumber":25,"sourceCode":"use tracing_util::{ErrorVisibility, TraceableError};\n\n#[derive(Clone)] // Cheap to clone as heavy fields are wrapped in `Arc`\npub struct EngineState {\n    pub expose_internal_errors: ExposeInternalErrors,\n    pub http_context: HttpContext,\n    pub graphql_state: Arc<gql::schema::Schema<GDS>>,\n    pub resolved_metadata: Arc<metadata_resolve::Metadata>,\n    pub jsonapi_catalog: Arc<jsonapi::Catalog>,\n    pub auth_config: Arc<ResolvedAuthConfig>,\n    pub graphql_websocket_server:\n        Arc<graphql_ws::WebSocketServer<graphql_ws::NoOpWebSocketMetrics>>,\n    pub auth_mode_header: String,\n}\n\n#[derive(thiserror::Error, Debug)]\n#[allow(clippy::enum_variant_names)]\npub enum StartupError {\n    #[error(\"could not read the auth config - {0}\")]\n    ReadAuth(anyhow::Error),\n    #[error(\"failed to build engine state - {0}\")]\n    ReadSchema(anyhow::Error),\n}\n\nimpl TraceableError for StartupError {\n    fn visibility(&self) -> tracing_util::ErrorVisibility {\n        ErrorVisibility::User\n    }\n}\n\n/// The type of request being made to the engine\npub enum RequestType {\n    Http,\n    WebSocket,\n}\n\nimpl RequestType {","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/v3/crates/engine/src/types.rs#L7-L43","documentation":"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.","triggerScenarios":"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.","commonSituations":"Missing auth config in deployments, malformed JSON after templating/envsubst, wrong file referenced by config, changed auth config schema between engine versions.","solutions":["Check the wrapped cause after the dash — it names the exact read/parse failure","Validate the auth config JSON with jq or a JSON schema before deploying","Ensure the file path in your server config points to the intended auth config","After upgrading the engine, re-check the expected auth config format"],"exampleFix":"// before\n{\"authn\": {\"authentication\": {\"jwt\": {\"issuer\": ...}}}}  // malformed/truncated\n\n// after\n# validate first\njq . auth_config.json && engine --authn-config-path ./auth_config.json","handlingStrategy":"validation","validationCode":"let raw = std::fs::read_to_string(&path).map_err(anyhow::Error::from)?;\nserde_json::from_str::<AuthConfig>(&raw)\n    .map_err(|e| StartupError::ReadAuth(e.into()))?;","typeGuard":"fn is_read_auth(e: &StartupError) -> bool { matches!(e, StartupError::ReadAuth(_)) }","tryCatchPattern":"Match StartupError::ReadAuth(err) at startup and print err (the wrapped cause) plus the configured path; exit non-zero.","preventionTips":["Validate auth config with jq/schema checks in CI","Template auth configs with a lint step after envsubst","Pin engine version and re-validate config format on upgrade"],"tags":["auth","config","startup","rust"],"backgroundTag":"auth-config-invalid","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}