Skip to content

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.1 or 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; use 0.3.1 or 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:

PlatformFolder
macOS~/Library/Tableau/Drivers
WindowsC:\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.

DialectWhat Tableau generates for dates and strings
MySQL (recommended)YEAR(…), MONTH(…), NOW(), CURDATE(), DATE_ADD(…), LEFT(…), LENGTH(…)
Generic SQL-92CAST(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
└── customers

Expand 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 WHERE and GROUP BY. Your query becomes the inner query of a SELECT … 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_name
FROM jdbc_join_emp e
JOIN 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

Tableau's data-source picker browsing Elasticsearch indices through SoftClient4ES

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.