• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / supavisor / 23816549911
79%

Build:
DEFAULT BRANCH: main
Ran 31 Mar 2026 08:01PM UTC
Jobs 2
Files 123
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

31 Mar 2026 07:53PM UTC coverage: 78.981% (-2.3%) from 81.271%
23816549911

push

github

web-flow
fix: SNI-based tenant routing  (#899)

## What is the current behavior?
SNI-based tenant routing silently fails across all tested versions
(2.7.4, 2.8.8, 2.9.0-rc). When a client connects with a plain username
(e.g. user=appuser) and relies on the TLS SNI hostname (e.g.
demo-db.local.arc.cloud) for tenant resolution, try_get_sni() returns
nil and the connection either falls back to dot-delimited username
routing or crashes with "comparison with nil is forbidden" in
Ecto.Query.Builder.


## What is the new behavior?
SNI-based tenant routing works end-to-end. Clients can connect with a
plain username and the tenant is correctly resolved from the TLS SNI
hostname. Pool identity and config lookups use the resolved tenant's
external_id.
## Additional context
Two separate bugs in lib/supavisor/client_handler.ex:

The :ssl.handshake call doesn't include an sni_fun callback. Erlang
OTP's :ssl module requires sni_fun to be registered during the handshake
for the SNI hostname to be captured and returned by
:ssl.connection_information/2. Without it, the handshake succeeds but
sni_hostname is never stored. Fixed by adding sni_fun: fn _hostname ->
[certs_keys: certs_keys] end to the handshake opts.


After SNI extraction works, the pool identity struct is still built with
tenant: tenant_or_alias, where tenant_or_alias is parsed from the
username and is nil for SNI-only connections. This nil propagates
through start_local_pool → get_pool_config_cache → get_pool_config,
where Ecto rejects the nil comparison. Fixed by falling back to
info.tenant.external_id when tenant_or_alias is nil.

## Personal Context
I was trying to run Supavisor with sni routing on K8s but it kept
failing for all tested versions (2.7.4, 2.8.8, 2.9.0-rc-3). Tried
looking into the code & fixing this, this change did fix the error


[logfile.txt](https://github.com/user-attachments/files/26358228/logfile.txt)
adding the error log i recieved when trying to connect using SNI routing
- it would fail... (continued)

2 of 2 new or added lines in 1 file covered. (100.0%)

60 existing lines in 3 files now uncovered.

2495 of 3159 relevant lines covered (78.98%)

58152.56 hits per line

Coverage Regressions

Lines Coverage ∆ File
41
84.74
-13.68% lib/supavisor/client_handler.ex
18
68.25
-15.69% lib/supavisor/helpers.ex
1
72.41
-3.45% lib/supavisor/handler_helpers.ex
Jobs
ID Job ID Ran Files Coverage
1 run-tests - 23816549911.1 31 Mar 2026 08:01PM UTC 123
77.59
GitHub Action Run
2 run-integration - 23816549911.2 31 Mar 2026 08:01PM UTC 123
42.42
GitHub Action Run
Source Files on build 23816549911
  • Tree
  • List 123
  • Changed 7
  • Source Changed 2
  • Coverage Changed 7
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #23816549911
  • bd4eff25 on github
  • Prev Build on main (#23727199329)
  • Next Build on main (#23853693667)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc