Skip to content

fix(mysql): retry SSLZeroReturnError peer-close on connect - #70542

Merged
Gilbert09 merged 1 commit into
masterfrom
posthog-code/mysql-ssl-closed-eof-retry
Jul 14, 2026
Merged

fix(mysql): retry SSLZeroReturnError peer-close on connect#70542
Gilbert09 merged 1 commit into
masterfrom
posthog-code/mysql-ssl-closed-eof-retry

Conversation

@Gilbert09

Copy link
Copy Markdown
Member

Problem

Error tracking surfaced an OperationalError(2003, "Can't connect to MySQL server on '<host>' (TLS/SSL connection has been closed (EOF) (_ssl.c:1032))") from the MySQL warehouse import source (issue). It was raised from _connect_with_transient_retry while reconnecting mid-sync.

The underlying cause is ssl.SSLZeroReturnError — the TLS peer closed the connection. This is exactly the transient class the source already retries in-process for the [SSL: UNEXPECTED_EOF_WHILE_READING] rendering (an overloaded server, a proxy/load-balancer idle cull, a failover, a momentary network blip). But _is_transient_connect_drop only matched that one token, so the SSLZeroReturnError rendering fell through: the retry re-raised on the first attempt, and the error then hit the non-retryable "Can't connect to MySQL server on" classifier. The sync gave up on a blip a fresh attempt would have recovered.

Changes

Recognize the second rendering of the SSL peer-close ("TLS/SSL connection has been closed (EOF)") as a transient connect drop, so both are retried in-process by _connect_with_transient_retry. Match the stable phrase only, not the volatile _ssl.c:<line> suffix, and keep it scoped to the 2003 branch so the generic "can't connect" config errors (wrong host/port, firewall) stay non-retryable.

This does not add anything to NonRetryableErrors and does not touch the global retry policy — the fix keeps a transient error retryable, which it should have been all along.

How did you test this code?

Extended TestIsTransientConnectDrop — parameterized the existing SSL peer-close case to cover both the UNEXPECTED_EOF_WHILE_READING and the new TLS/SSL connection has been closed (EOF) renderings. Guards against re-narrowing the matcher so the new rendering silently becomes non-retryable again; no existing case exercised it.

Ran locally:

python -m pytest test_mysql.py::TestIsTransientConnectDrop test_mysql.py::TestConnectTransientRetry
19 passed

Also ran ruff check and ruff format --check on both changed files — clean.

🤖 Agent context

Autonomy: Fully autonomous

Triaged from an error-tracking webhook by Claude (Claude Code). Pulled the issue and a representative event via the PostHog MCP error-tracking tools, read the full stack trace to confirm the failure originates in mysql.py (_connect_with_transient_retry), and read the source's existing transient/non-retryable classification.

Decision: fixable bug, not a user/upstream error. The message is a transient infrastructure drop, and the source already treats the sibling SSL-EOF token as retryable — this rendering just wasn't matched. So the fix is to widen the transient matcher, not to add a NonRetryableErrors entry. Invoked /writing-tests before touching the test file; chose to parameterize the existing test rather than add a near-duplicate.


Created with PostHog Code

The transient-connect-drop detection only matched the
`[SSL: UNEXPECTED_EOF_WHILE_READING]` rendering of an SSL peer-close. Newer
OpenSSL/Python raise `ssl.SSLZeroReturnError` ("TLS/SSL connection has been
closed (EOF)") for the same condition, which pymysql wraps as the same 2003
connect failure. That message wasn't recognized as transient, so the in-process
retry re-raised it immediately and it hit the non-retryable "Can't connect to
MySQL server on" classifier — giving up the sync on a momentary TLS drop.

Match the new token too so both renderings are retried in-process.

Generated-By: PostHog Code
Task-Id: e6712d85-56fe-4698-a9e1-d8eee288c2f0
@github-actions

Copy link
Copy Markdown
Contributor

Hey @Gilbert09! 👋

It looks like your git author email on this PR isn't your @posthog.com address (owerstom@gmail.com). Since you're on the PostHog team, it's worth pointing your local git author email at your @posthog.com address. Why it matters:

  • Consistent work identity in git history — internal tooling that attributes commits to team members keys off your @posthog.com address.
  • Keeps team contributions easy to tell apart from external community ones when scanning history.

You can fix it for this repo with:

git config user.email "you@posthog.com"

Or set it globally with git config --global user.email "you@posthog.com". No need to redo this PR — just a nudge for next time. 🙂

@pr-assigner-resolver-posthog
pr-assigner-resolver-posthog Bot requested a review from a team July 13, 2026 18:14
@greptile-apps

greptile-apps Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "fix(mysql): retry SSLZeroReturnError pee..." | Re-trigger Greptile

@Gilbert09 Gilbert09 added the stamphog Request AI approval (no full review) label Jul 13, 2026 — with PostHog

@stamphog stamphog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small, well-tested widening of a transient-error string match in the MySQL warehouse connector; author is on the owning team with strong familiarity, no risky-territory concerns, no unresolved review comments.

  • Author wrote 100% of the modified lines and has 13 merged PRs in these paths (familiarity STRONG).
  • 👍 on the PR from greptile-apps[bot], hex-security-app[bot].
Gate mechanics and policy version
Gate Result
prerequisites all clear
deny-list no deny categories matched
size 19L, 1F substantive, 45L/2F incl. docs/generated/snapshots — within ceiling
tier T1-agent / T1b-small (45L, 2F, single-area, fix)
stamphog 2.0.0b3 .stamphog/policy.yml @ 0a0a844 · reviewed head 0013d16

@trunk-io

trunk-io Bot commented Jul 13, 2026

Copy link
Copy Markdown

Static BadgeStatic BadgeStatic BadgeStatic Badge

View Full Report ↗︎Docs

@Gilbert09
Gilbert09 merged commit 62fede4 into master Jul 14, 2026
318 of 320 checks passed
@Gilbert09
Gilbert09 deleted the posthog-code/mysql-ssl-closed-eof-retry branch July 14, 2026 09:27
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 14, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-14 09:50 UTC Run
prod-us ✅ Deployed 2026-07-14 10:05 UTC Run
prod-eu ✅ Deployed 2026-07-14 10:06 UTC Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stamphog Request AI approval (no full review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant