Tableau
Tableau connects to Elasticsearch through the SoftClient4ES JDBC driver, using Tableau’s built-in Other Databases (JDBC) connector.
Compatible — the connection path is a standard JDBC surface and we have driven Tableau against it in the lab, but Tableau is not part of our formal regression suite and these steps have not been run end to end on a clean install. Best-effort.
Before you start
- SoftClient4ES JDBC driver
0.3.1or later. Earlier drivers cannot start inside Tableau — Tableau installs its own class loader, and older builds fail to read their own configuration under it. There is no workaround, no JVM flag and no properties file that fixes an earlier version; use0.3.1or later. - Tableau Desktop, with the Other Databases (JDBC) connector. That is the connector Tableau documents for third-party JDBC drivers, and Tableau Desktop is the product its JDBC documentation covers.
- Tableau’s own caveat, worth reading once: it “provides no guarantee or warranty that using the Other Databases (JDBC) connector with any particular JDBC driver or database will be able to successfully connect and query data”.
Connect
1. Put the driver where Tableau looks for it
Download the SoftClient4ES JDBC fat JAR for your Elasticsearch major version — for example
softclient4es8-jdbc-driver-0.3.3.jar for ES 8.x — from the download table,
and copy it into Tableau’s driver folder:
| Platform | Folder |
|---|---|
| macOS | ~/Library/Tableau/Drivers |
| Windows | C:\Program Files\Tableau\Drivers |
| Linux | /opt/tableau/tableau_driver/jdbc |
Create the folder if it does not exist, then restart Tableau — it scans the folder at start-up only. A JAR in any other location is not an error you will see: Tableau simply reports that no driver is available.
On macOS, Tableau documents two locations. Its Other Databases (JDBC) page names
~/Library/Tableau/Drivers; its Tableau and JDBC page names ~/Library/JDBC (or /Library/JDBC for
all users). If Tableau still reports no driver after a restart, put a copy in ~/Library/JDBC too.
(Folder locations from Tableau’s Other Databases (JDBC) and Tableau and JDBC pages, checked 2026-09-01.)
2. Create the connection
Connect → To a Server → Other Databases (JDBC), then fill in:
- URL:
jdbc:elastic://localhost:9200 - Dialect:
MySQL— see Choosing the dialect below - With authentication, put the credentials in the URL:
jdbc:elastic://es.example.com:9243?scheme=https&user=elastic&password=changeme
Tableau’s JDBC connector has no driver-class field — the URL prefix jdbc:elastic:// is what selects
the driver, and the fat JAR registers itself. The driver class, if another tool asks for it, is
app.softnetwork.elastic.jdbc.ElasticDriver. The fat JAR is self-contained and Scala-version-independent
— there is no Scala suffix to choose.
Choosing the dialect
Tableau’s generic JDBC connector offers exactly three dialects — MySQL, PostgreSQL and Generic SQL-92 — and Tableau states that with Other Databases (JDBC), “the outcome may vary and compatibility with Tableau Desktop features is not guaranteed”.
Pick MySQL unless you have a reason not to. The dropdown changes the spelling Tableau generates,
not what SoftClient4ES can compute — every function on both sides is implemented; see the
SQL reference.
| Dialect | What Tableau generates for dates and strings |
|---|---|
| MySQL (recommended) | YEAR(…), MONTH(…), NOW(), CURDATE(), DATE_ADD(…), LEFT(…), LENGTH(…) |
| Generic SQL-92 | CAST(EXTRACT(… FROM …) AS INTEGER), CURRENT_TIMESTAMP, SUBSTRING(… FROM … FOR …) |
We have measured what Tableau emits under both dialects; PostgreSQL is the third option and we have not exercised it. The dialect is not what decides whether a drag-and-drop worksheet runs today — see Running queries below. If you switch dialects on an existing data source, expect Tableau to regenerate its SQL.
Browse
Once connected, Tableau’s data-source picker shows a two-level namespace above your indices:
elasticsearch ← database (always this name)└── my-cluster ← schema (your Elasticsearch cluster name) ├── orders ← your indices, as tables └── customersExpand the schema to list your indices, and select one to see its columns. If the driver cannot read the
cluster name — for example on a cluster that restricts the cluster-info API — the schema is shown as
default and browsing still works.
Running queries
Connecting and browsing your indices is what this release delivers from Tableau. Two things to know before you build a worksheet, because both are about SQL Tableau writes for you:
- Drag-and-drop worksheets generate SQL that quotes and fully qualifies every identifier
(backticks under the MySQL dialect,
"schema"."table"under Generic SQL-92). SoftClient4ES does not accept that spelling yet; support for it lands in an upcoming release. - Custom SQL is not a way around that. Tableau does not send a Custom SQL query as you typed it:
“Tableau must wrap the custom SQL statement within a select statement”, so that it can add its own
WHEREandGROUP BY. Your query becomes the inner query of aSELECT … FROM ( … )— a derived table, which arrives with the same release as subquery support. (Tableau’s Custom SQL documentation, checked 2026-09-01.)
Extract mode narrows the exposure but does not remove it: Tableau still materialises an extract by querying the source, and with a Custom SQL data source that query is the wrapped one. We have not measured extract creation against SoftClient4ES — treat it as untested rather than as a workaround.
See Known Limitations for what the current release does and does not accept, and for the release timing.
The temp-table probe
On every connection Tableau checks whether it can create a temporary table, by issuing a
CREATE TABLE / DROP TABLE pair against a generated name. SoftClient4ES has no temporary tables —
an Elasticsearch index is cluster-global and has no session scope — so that pair is refused with an
HTTP 400 naming the statement and the reason, and Tableau moves on. Refusing is a supported path:
Tableau’s own connector documentation says that when the temp-table capabilities are disabled,
“Tableau will attempt to generate an alternative query to retrieve the necessary results.”
The probe therefore costs one failed round trip per connection, and is not itself the problem. What follows it can be: Tableau’s alternative for a source without temporary tables uses subqueries, which this release does not accept, so some interactions fail — with the same kind of clear error naming the statement, never a hang and never a silently wrong answer. Tableau’s own documentation also warns that the subquery path “can be poor, particularly with large datasets.”
A Tableau Datasource Customization file (.tdc) cannot suppress the probe, and SoftClient4ES ships
none. The capability that would do it, CAP_SUPPRESS_TEMP_TABLE_CHECKS, is not among the
capabilities Tableau documents for JDBC connections: the JDBC Capability Customizations
Reference lists
CAP_CREATE_TEMP_TABLES and around sixty others, but not that one — it belongs to the Connector SDK
capability set, which a packaged .taco connector declares. Writing a .tdc for it is a dead end
worth not walking down.
Cross-index JOIN
The superpower of this release: Elasticsearch SQL can’t JOIN across indices — SoftClient4ES does. This is the query worth running first, and you can run it today from DBeaver or Apache Superset, where you control the SQL that is sent:
SELECT e.name, e.salary, d.dept_nameFROM jdbc_join_emp eJOIN jdbc_join_dept d ON e.dept_id = d.dept_id;-- 5 rows (the orphan employee with dept_id=99 is dropped by the INNER JOIN)For the full JOIN matrix (INNER / LEFT / RIGHT / FULL / cross-cluster), see the Cross-Index JOIN walkthrough. JOIN depth and cluster count are metered — see Pricing.
Screenshot
Screenshot coming in a follow-up release.
License
The JDBC driver is licensed under the Elastic License 2.0 — free to use, not open source.