fix(kafka): name the profile and env var when SASL credentials are missing - #95874
Conversation
…ssing The router now rejects a cluster profile that uses SASL_PLAINTEXT or SASL_SSL while a SASL credential is unset. The error names the profile and the KAFKA_<PROFILE>_SASL_* vars, instead of librdkafka's _INVALID_ARG, which names neither. The check runs in `get_profile_settings`, so every producer and consumer that routes through it reports the same message. Self-hosted base64 cert mode is exempt, because it forces the protocol to SSL and attaches no credentials. The DLQ replay activities drop their own copy of the check and reuse this one. Generated-By: PostHog Desktop Task-Id: d2888f81-46cf-416c-922d-d3e6a417e1e2
🤖 CI report
|
There was a problem hiding this comment.
Not approved — escalated to a human reviewer.
Re-add the stamphog label to request another review once you have addressed this.
This rewires how every Kafka producer and consumer resolves its cluster profile (an event-ingestion path shared by health checks, activity-log, and usage events), and no completed review or approval exists yet — the only discussion comment is an automated review still at step 1 of 6, so there is no independent assurance to rely on.
- Change touches the shared Kafka producer/consumer profile-resolution path (event ingestion), which is risky territory per policy.
- No completed human or agent review exists on the current head — the automated PostHog review comment shows it is still in progress (step 1/6), not a finished verdict.
- No ownership match in owners.yaml/product.yaml, and the author is a machine implementation bot so familiarity/org-membership signals don't apply.
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✓ | no deny categories matched |
| size | ✓ | 69L, 3F substantive, 141L/6F incl. docs/generated/snapshots — within ceiling |
| tier | ✓ | T1-agent / T1c-medium (141L, 6F, single-area, fix) |
| stamphog 2.0.0b4 | .stamphog/policy.yml @ c66dcae · reviewed head c66dcae |
…s-to-9a9246' into posthog-self-driving/fixkafka-fail-loudly-when-a-cluster-c48187 Generated-By: PostHog Desktop Task-Id: d2888f81-46cf-416c-922d-d3e6a417e1e2
There was a problem hiding this comment.
Approved.
Touches the Kafka producer/consumer resolution path (event ingestion), but the change is well-scoped, tested (new unit tests for the validation, the base64 exemption, and the DLQ non-retryable wrapping), verified against the fallback env-var chain so it can't false-positive, and the automated PostHog review bot found no concerns.
Gate mechanics and policy version
| Gate | Result | |
|---|---|---|
| prerequisites | ✓ | all clear |
| deny-list | ✓ | no deny categories matched |
| size | ✓ | 69L, 3F substantive, 141L/6F incl. docs/generated/snapshots — within ceiling |
| tier | ✓ | T1-agent / T1c-medium (141L, 6F, single-area, fix) |
| stamphog 2.0.0b4 | .stamphog/policy.yml @ 4540f89 · reviewed head 4540f89 |

Problem
produce_internal_eventpath, so all three go silent together._resolve_profileaccepts a profile with a SASL protocol and no credentials, and_build_sasl_confighands it to librdkafka anyway._INVALID_ARG: sasl.username and sasl.password must be set, which names no profile and no env var, so the reader goes after the cluster.get_producercaches only on success, so every produce attempt rebuilds the producer and raises the same message again.Changes
get_profile_settings, the one place every routed producer and consumer resolves a profile through. Both producer builders now route through it too._resolve_profileitself. That runs at settings import for every profile, so a raise there would stop a process from booting over a profile it never produces to.KafkaProfileSettingsgainsuses_saslandcheck_sasl_credentials.Note
A profile that is configured correctly is unaffected: the check runs on every profile resolution but only raises when the protocol needs SASL.
How did you test this code?
posthog/kafka_client/test/test_kafka_settings.pycover the regression: a SASL profile that misses the mechanism, the user, or the password raises an error naming that profile and that env var. No existing test looked at credential completeness.GetProfileSettingsTestinposthog/kafka_client/test/test_routing.pypins the two router decisions: a SASL profile with no credentials is rejected, and base64 cert mode is exempt.uv run mypy --cache-fine-grained .is clean.posthog/kafka_client/test/test_client.pyneeds a live ClickHouse, which this sandbox has no access to. Those 9 tests error at setup on the same connection refusal before and after the change. No produce ran against a real SASL cluster.Automatic notifications
Docs update
None. No documented workflow or config surface changes.
🤖 Agent context
Autonomy: Fully autonomous
/writing-pr-descriptions,/writing-simplified-technical-english,/simplify,/writing-tests.hosts_configuredand the DLQ replay fail-fast path. This layer moves the SASL half of that check onto the profile itself, so one implementation serves every caller._resolve_profile. It is the site the report named, but it runs at settings import, so a half-configured profile would take down a whole process rather than the produce path that uses it._build_sasl_config. It has the credentials but not the profile name, so its message could not name the env var to set._KafkaProducerand the warehouse person-property consumer both force the protocol to SSL in that mode. Without the exemption a working self-hosted deployment would start failing.Created with PostHog Desktop from this inbox report.