{"record":{"id":"038623e20a78fc91","repo":"block/buzz","slug":"git-conformance-probe-failed-e","errorCode":null,"errorMessage":"git conformance probe failed: {e}","messagePattern":"git conformance probe failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/buzz-relay/src/main.rs","lineNumber":528,"sourceCode":"            .unwrap_or(32);\n        let race_rounds = std::env::var(\"BUZZ_GIT_PROBE_ROUNDS\")\n            .ok()\n            .and_then(|v| v.parse().ok())\n            .unwrap_or(3);\n        let cfg = buzz_relay::api::git::store::ProbeConfig {\n            race_width,\n            race_rounds,\n        };\n        tracing::info!(\n            race_width,\n            race_rounds,\n            \"running git object-store conformance probe (A3 gate)\"\n        );\n        let report = state\n            .git_store\n            .run_conformance_probe(cfg)\n            .await\n            .map_err(|e| anyhow::anyhow!(\"git conformance probe failed: {e}\"))?;\n        tracing::info!(\n            race_width = report.race_width,\n            race_rounds = report.race_rounds,\n            transport_drops = report.transport_drops,\n            \"git object-store backend admitted: A3 conformance probe passed\"\n        );\n    }\n\n    // NIP-43: reconcile the event-backed roster for every provisioned\n    // community before opening the listener. `relay_members` is canonical;\n    // this repairs pre-snapshot communities and any publication that failed\n    // after a membership transaction committed.\n    if config.require_relay_membership {\n        match buzz_relay::handlers::side_effects::reconcile_nip43_membership_snapshots(&state).await\n        {\n            Ok(count) => info!(count, \"NIP-43 membership snapshots reconciled on startup\"),\n            Err(error) => {\n                tracing::warn!(%error, \"NIP-43 membership snapshot startup reconciliation failed\")","sourceCodeStart":510,"sourceCodeEnd":546,"githubUrl":"https://github.com/block/buzz/blob/f956e6fe06a76e50cbd8fba1a162482e752e7f1a/crates/buzz-relay/src/main.rs#L510-L546","documentation":"A fatal startup gate in buzz-relay: before serving git traffic, main() runs run_conformance_probe (crates/buzz-relay/src/api/git/store.rs:576) against the configured S3/MinIO backend (GitStore is built from the same BUZZ_S3_* media config, state.rs:836) to verify the linearizable conditional-write axiom A3. Four phases execute: sequential write/read-back, race_width parallel If-Match CAS updates of one pointer (exactly one winner allowed), race_width parallel create-only If-None-Match writes, and an ETag read-to-CAS round-trip. Any phase failure returns StoreError::Probe(ProbeFailure{phase, round, key, reason}); transport/auth problems return StoreError::Backend. main.rs wraps either as this error and the relay refuses to come up, because a backend without linearizable pointer CAS silently corrupts the git manifest-pointer protocol.","triggerScenarios":"Booting with BUZZ_GIT_CONFORMANCE_PROBE unset or != \"false\" (probe runs by default) while the BUZZ_S3_* backend is unreachable, has bad credentials/bucket, or is S3-compatible but not conditional-write-conformant. Specific probe failures: 'sequential' read-after-write mismatch or 403 on PUT; 'if_match_race'/'if_none_match_race' with more than one 2xx winner (backend ignores If-Match/If-None-Match or returns 200 instead of 412); 'etag_consistency' when the ETag changes between get and IfMatch; missing ETag header on a successful CAS; 'config' phase when BUZZ_GIT_PROBE_WRITERS < 2 or BUZZ_GIT_PROBE_ROUNDS = 0.","commonSituations":"MinIO or an S3 gateway that lacks or weakens conditional writes / rewrites ETags (older MinIO, some object-store proxies); wrong credentials so every PUT fails; CI spinning up a MinIO without conditional-write support; pointing BUZZ_S3_ENDPOINT at the wrong scheme or port; developers who only want chat features and hit an unexpected S3 gate at boot.","solutions":["Read the phase and reason inside the error text: phase=sequential points at credentials/read-after-write, phase=if_match_race/if_none_match_race at non-linearizable conditional writes, phase=etag_consistency at unstable ETag tokens, phase=config at bad BUZZ_GIT_PROBE_* values.","Reproduce against the backend directly with the store's live probe: BUZZ_GIT_S3_PROBE=1 cargo test -p buzz-relay --lib using your BUZZ_S3_* values (see store.rs test docs).","Fix the backend: use an S3 implementation with real conditional writes and stable ETags (AWS S3, current MinIO), and correct BUZZ_S3_ENDPOINT/BUZZ_S3_BUCKET/keys/region and BUZZ_S3_ADDRESSING_STYLE.","If transport flakiness caused racer drops to fail a round, re-run with a smaller BUZZ_GIT_PROBE_WRITERS (default 32) — it must stay >= 2 and BUZZ_GIT_PROBE_ROUNDS >= 1.","Non-production only: set BUZZ_GIT_CONFORMANCE_PROBE=false to skip the gate, accepting an unsafe backend for git traffic."],"exampleFix":"# before (relay exits: \"git conformance probe failed: probe phase=if_none_match_race ... multiple winners\")\nBUZZ_S3_ENDPOINT=http://minio:9000\nBUZZ_S3_BUCKET=buzz-media\n\n# after — either fix the backend (upgrade MinIO to a conditional-write build),\n# or explicitly skip the gate in dev only:\nBUZZ_GIT_CONFORMANCE_PROBE=false","handlingStrategy":"validation","validationCode":"// Before boot, canary-check the S3 backend with a cheap probe run\n// (minimum legal width, 1 round) so deploy pipelines fail before the relay does:\nlet cfg = ProbeConfig { race_width: 2, race_rounds: 1 };\nlet report = git_store.run_conformance_probe(cfg).await\n    .map_err(|e| anyhow::anyhow!(\"deploy blocked: S3 backend not conformant: {e}\"))?;\nif report.transport_drops > 0 {\n    tracing::warn!(drops = report.transport_drops, \"S3 endpoint is flaky\");\n}","typeGuard":"use buzz_relay::api::git::store::StoreError;\n\n// Backend answered but violated an axiom (replace/upgrade the backend).\nfn is_conformance_violation(e: &StoreError) -> bool {\n    matches!(e, StoreError::Probe(_))\n}\n\n// Backend never answered usefully (creds/endpoint/transport).\nfn is_backend_reachability(e: &StoreError) -> bool {\n    matches!(e, StoreError::Backend(_))\n}","tryCatchPattern":"match state.git_store.run_conformance_probe(cfg).await {\n    Ok(report) => tracing::info!(?report, \"backend admitted\"),\n    Err(e) if matches!(e, StoreError::Probe(_)) => {\n        return Err(anyhow!(\"backend reachable but non-conformant — replace it: {e}\"))\n    }\n    Err(e) => {\n        return Err(anyhow!(\"backend unreachable/misconfigured — check BUZZ_S3_*: {e}\"))\n    }\n}","preventionTips":["Pin MinIO/S3 gateway versions in CI that are known to implement If-Match/If-None-Match and stable ETags","Run the conformance probe as a deploy-pipeline canary before rolling the relay out","Never set BUZZ_GIT_CONFORMANCE_PROBE=false in production — pointer CAS corruption is silent","Keep BUZZ_GIT_PROBE_WRITERS >= 2 and BUZZ_GIT_PROBE_ROUNDS >= 1; the probe's config phase rejects anything smaller"],"tags":["rust","s3","minio","conditional-writes","etags","startup","conformance-probe"],"backgroundTag":"s3-conditional-writes-unsupported","analyzedSha":"f956e6fe06a76e50cbd8fba1a162482e752e7f1a","analyzedAt":"2026-08-16T22:11:40.750Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}