No suitable driver found for JDBC connection

Hi,

We are developing custom driver for Metabase to connect with Firebolt Data Source.
While setting up the connection to Firebolt from metabase we are facing below error

Error: -
POST /api/setup/validate 400 22.5 ms (0 DB calls)
{:errors {:dbname "No suitable driver found for jdbc:firebolt://api.app.firebolt.io:8123/Sigmoid_Alchemy"}}

Hi @anshulhiran
It's difficult to say. Is the driver developed for the same version of Metabase as you're trying to test it on?
There has been a lot of changes in 0.41 compared to previously. We currently haven't updated all the developer information, so if you're new to drivers, it might be tricky for you.

below is the stack trace

2021-10-22 15:43:32,319 DEBUG middleware.log :: POST /api/setup/validate 400 24.4 ms (0 DB calls)
{:errors
{:dbname
"No suitable driver found for jdbc:firebolt://sigmoid-alchemy-ingest.sigmoidanalytics.us-east-1.app.firebolt.io:8123/Sigmoid_Alchemy"}}
2021-10-22 15:43:32,332 ERROR driver.util :: Database connection error
java.sql.SQLException: No suitable driver found for jdbc:firebolt://sigmoid-alchemy-ingest.sigmoidanalytics.us-east-1.app.firebolt.io:8123/Sigmoid_Alchemy
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:702)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:189)
at clojure.java.jdbc$get_driver_connection.invokeStatic(jdbc.clj:271)
at clojure.java.jdbc$get_driver_connection.invoke(jdbc.clj:250)
at clojure.java.jdbc$get_connection.invokeStatic(jdbc.clj:411)
at clojure.java.jdbc$get_connection.invoke(jdbc.clj:274)
at clojure.java.jdbc$db_query_with_resultset_STAR_.invokeStatic(jdbc.clj:1111)
at clojure.java.jdbc$db_query_with_resultset_STAR_.invoke(jdbc.clj:1093)
at clojure.java.jdbc$query.invokeStatic(jdbc.clj:1182)
at clojure.java.jdbc$query.invoke(jdbc.clj:1144)
at clojure.java.jdbc$query.invokeStatic(jdbc.clj:1160)
at clojure.java.jdbc$query.invoke(jdbc.clj:1144)
at metabase.driver.firebolt$fn__428.invokeStatic(firebolt.clj:63)
at metabase.driver.firebolt$fn__428.invoke(firebolt.clj:61)
at clojure.lang.MultiFn.invoke(MultiFn.java:234)
at metabase.driver.util$can_connect_with_details_QMARK_$fn__24605.invoke(util.clj:34)
at metabase.util$do_with_timeout$fn__6172.invoke(util.clj:354)
at clojure.core$binding_conveyor_fn$fn__5772.invoke(core.clj:2034)
at clojure.lang.AFn.call(AFn.java:18)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
2021-10-22 15:43:32,335 ERROR api.database :: Cannot connect to Database
java.lang.Exception: No suitable driver found for jdbc:firebolt://sigmoid-alchemy-ingest.sigmoidanalytics.us-east-1.app.firebolt.io:8123/Sigmoid_Alchemy
at metabase.driver.util$can_connect_with_details_QMARK_.invokeStatic(util.clj:39)
at metabase.driver.util$can_connect_with_details_QMARK_.doInvoke(util.clj:22)
at clojure.lang.RestFn.invoke(RestFn.java:442)
at metabase.api.database$test_database_connection.invokeStatic(database.clj:414)
at metabase.api.database$test_database_connection.doInvoke(database.clj:404)
at clojure.lang.RestFn.invoke(RestFn.java:464)
at metabase.api.setup$fn__77545.invokeStatic(setup.clj:136)
at metabase.api.setup$fn__77545.invoke(setup.clj:127)
at compojure.core$wrap_response$fn__32047.invoke(core.clj:160)
at compojure.core$wrap_route_middleware$fn__32031.invoke(core.clj:132)
at compojure.core$wrap_route_info$fn__32036.invoke(core.clj:139)
at compojure.core$wrap_route_matches$fn__32040.invoke(core.clj:151)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$wrap_route_matches$fn__32040.invoke(core.clj:152)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$wrap_route_matches$fn__32040.invoke(core.clj:153)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059.invoke(core.clj:200)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059.invoke(core.clj:200)
at compojure.core$make_context$handler__32087.invoke(core.clj:289)
at compojure.core$make_context$fn__32091.invoke(core.clj:299)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$make_context$fn__32091.invoke(core.clj:300)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at metabase.api.routes$fn__79711$fn__79714.invoke(routes.clj:56)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059.invoke(core.clj:200)
at clojure.lang.AFn.applyToHelper(AFn.java:160)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.core$apply.invokeStatic(core.clj:667)
at clojure.core$apply.invoke(core.clj:662)
at metabase.server.routes$fn__79856$fn__79857.doInvoke(routes.clj:57)
at clojure.lang.RestFn.invoke(RestFn.java:436)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059.invoke(core.clj:200)
at compojure.core$make_context$handler__32087.invoke(core.clj:289)
at compojure.core$make_context$fn__32091.invoke(core.clj:299)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$wrap_route_matches$fn__32040.invoke(core.clj:153)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$wrap_route_matches$fn__32040.invoke(core.clj:153)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at compojure.core$wrap_route_matches$fn__32040.invoke(core.clj:153)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059$f__32060$respond_SINGLEQUOTE___32061.invoke(core.clj:197)
at metabase.server.routes$fn__79844$fn__79846.invoke(routes.clj:41)
at compojure.core$routes$fn__32059$f__32060.invoke(core.clj:198)
at compojure.core$routes$fn__32059.invoke(core.clj:200)
at metabase.server.middleware.exceptions$catch_uncaught_exceptions$fn__77318.invoke(exceptions.clj:98)
at metabase.server.middleware.exceptions$catch_api_exceptions$fn__77315.invoke(exceptions.clj:86)
at metabase.server.middleware.log$log_api_call$fn__80311$fn__80312$fn__80313.invoke(log.clj:209)
at metabase.driver.sql_jdbc.execute.diagnostic$do_with_diagnostic_info.invokeStatic(diagnostic.clj:15)
at metabase.driver.sql_jdbc.execute.diagnostic$do_with_diagnostic_info.invoke(diagnostic.clj:9)
at metabase.server.middleware.log$log_api_call$fn__80311$fn__80312.invoke(log.clj:201)
at toucan.db$_do_with_call_counting.invokeStatic(db.clj:216)
at toucan.db$_do_with_call_counting.invoke(db.clj:209)
at metabase.server.middleware.log$log_api_call$fn__80311.invoke(log.clj:200)
at metabase.server.middleware.browser_cookie$ensure_browser_id_cookie$fn__83524.invoke(browser_cookie.clj:30)
at metabase.server.middleware.security$add_security_headers$fn__59173.invoke(security.clj:144)
at metabase.server.middleware.json$wrap_json_body$fn__82668.invoke(json.clj:62)
at metabase.server.middleware.json$wrap_streamed_json_response$fn__82686.invoke(json.clj:98)
at metabase.server.middleware.offset_paging$handle_paging$fn__59197.invoke(offset_paging.clj:42)
at ring.middleware.keyword_params$wrap_keyword_params$fn__83791.invoke(keyword_params.clj:55)
at ring.middleware.params$wrap_params$fn__83807.invoke(params.clj:69)
at metabase.server.middleware.misc$maybe_set_site_url$fn__34057.invoke(misc.clj:59)
at metabase.server.middleware.session$bind_current_user$fn__44959$fn__44960.invoke(session.clj:257)
at metabase.server.middleware.session$do_with_current_user.invokeStatic(session.clj:238)
at metabase.server.middleware.session$do_with_current_user.invoke(session.clj:230)
at metabase.server.middleware.session$bind_current_user$fn__44959.invoke(session.clj:256)
at metabase.server.middleware.session$wrap_current_user_info$fn__44946.invoke(session.clj:216)
at metabase.server.middleware.session$wrap_session_id$fn__44932.invoke(session.clj:162)
at metabase.server.middleware.auth$wrap_api_key$fn__70244.invoke(auth.clj:27)
at ring.middleware.cookies$wrap_cookies$fn__83711.invoke(cookies.clj:216)
at metabase.server.middleware.misc$add_content_type$fn__34040.invoke(misc.clj:27)
at metabase.server.middleware.misc$disable_streaming_buffering$fn__34065.invoke(misc.clj:76)
at ring.middleware.gzip$wrap_gzip$fn__83753.invoke(gzip.clj:86)
at metabase.server.middleware.misc$bind_request$fn__34068.invoke(misc.clj:93)
at metabase.server.middleware.ssl$redirect_to_https_middleware$fn__83540.invoke(ssl.clj:38)
at metabase.server$async_proxy_handler$fn__80084.invoke(server.clj:71)
at metabase.server.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a.handle(Unknown Source)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:516)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:386)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.sql.SQLException: No suitable driver found for jdbc:firebolt://sigmoid-alchemy-ingest.sigmoidanalytics.us-east-1.app.firebolt.io:8123/Sigmoid_Alchemy
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:702)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:189)
at clojure.java.jdbc$get_driver_connection.invokeStatic(jdbc.clj:271)
at clojure.java.jdbc$get_driver_connection.invoke(jdbc.clj:250)
at clojure.java.jdbc$get_connection.invokeStatic(jdbc.clj:411)
at clojure.java.jdbc$get_connection.invoke(jdbc.clj:274)
at clojure.java.jdbc$db_query_with_resultset_STAR_.invokeStatic(jdbc.clj:1111)
at clojure.java.jdbc$db_query_with_resultset_STAR_.invoke(jdbc.clj:1093)
at clojure.java.jdbc$query.invokeStatic(jdbc.clj:1182)
at clojure.java.jdbc$query.invoke(jdbc.clj:1144)
at clojure.java.jdbc$query.invokeStatic(jdbc.clj:1160)
at clojure.java.jdbc$query.invoke(jdbc.clj:1144)
at metabase.driver.firebolt$fn__428.invokeStatic(firebolt.clj:63)
at metabase.driver.firebolt$fn__428.invoke(firebolt.clj:61)
at clojure.lang.MultiFn.invoke(MultiFn.java:234)
at metabase.driver.util$can_connect_with_details_QMARK_$fn__24605.invoke(util.clj:34)
at metabase.util$do_with_timeout$fn__6172.invoke(util.clj:354)
at clojure.core$binding_conveyor_fn$fn__5772.invoke(core.clj:2034)
at clojure.lang.AFn.call(AFn.java:18)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
... 1 more
2021-10-22 15:43:32,351 DEBUG middleware.log :: POST /api/setup/validate 400 10.4 ms (0 DB calls)
{:errors
{:dbname
"No suitable driver found for jdbc:firebolt://...."}}

@anshulhiran You didn't really answer any questions. Try linking to your repo, so people can see your code and perhaps help.