Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Logstash By James Joyner IV · · 9 min read

Logstash Error Guide: 'could not load driver class com.mysql.jdbc.Driver' — Fix the JDBC Input Driver

Quick answer

Fix Logstash jdbc input 'could not load driver class': set jdbc_driver_library and jdbc_driver_class correctly, verify the JAR path, and test it.

  • #logstash
  • #logging
  • #troubleshooting
  • #errors
Free toolkit

Fixing errors like this? Get 500 free DevOps AI prompts

500 copy-paste AI prompts for the stack you actually run — one PDF, free.

Overview

The Logstash jdbc input plugin loads a database driver class by name at pipeline startup. When the JAR that contains that class is not on the classpath — or the class name is misspelled, or points at a driver that no longer exists in your connector version — the plugin throws a ClassNotFoundException and the pipeline never reaches the query stage. The most common form of this error looks like this in /var/log/logstash/logstash-plain.log:

[ERROR][logstash.inputs.jdbc][main][a1b2...] Unable to connect to database. Tried 1 times {:message=>"Java::JavaLang::ClassNotFoundException: com.mysql.jdbc.Driver"}

You will also see the closely related Sequel/JRuby wrapper message that names the same missing class:

[ERROR][logstash.javapipeline][main] Pipeline error {:pipeline_id=>"main", :exception=>#<Sequel::DatabaseConnectionError: Java::JavaLang::ClassNotFoundException: could not load driver class com.mysql.jdbc.Driver>}

In plain terms: Logstash asked the JVM to instantiate the driver class you named in jdbc_driver_class, and the JVM could not find a class by that name in any JAR it was told about via jdbc_driver_library. There are only two moving parts here — the library (the physical JAR) and the class (the fully-qualified name inside it) — and this error means at least one of them is wrong.

Symptoms

  • The pipeline that owns the jdbc input fails to start, or starts and immediately logs a Pipeline error and shuts that pipeline down.
  • logstash-plain.log shows ClassNotFoundException naming a driver class such as com.mysql.jdbc.Driver, com.mysql.cj.jdbc.Driver, org.postgresql.Driver, or oracle.jdbc.OracleDriver.
  • No rows are ever emitted; downstream Elasticsearch indices stay empty even though the database is reachable from the host.
  • bin/logstash --config.test_and_exit passes (the syntax is valid) but the pipeline still fails at runtime, because driver loading happens when the input starts, not during config parsing.
  • With MySQL Connector/J 8.x, the log names com.mysql.jdbc.Driver as missing even though the JAR is present — because that class was renamed.

Common Root Causes

  • Missing jdbc_driver_library — the input block sets jdbc_driver_class but never points jdbc_driver_library at a JAR, so the class is nowhere on the classpath.
  • Wrong path to the JARjdbc_driver_library points at a file that does not exist (typo, wrong directory, or a path only valid on the developer’s laptop). Logstash silently proceeds and only fails when the class cannot be found.
  • Renamed driver class in newer connectors — MySQL Connector/J 8.x replaced com.mysql.jdbc.Driver with com.mysql.cj.jdbc.Driver. Configs copied from old tutorials still name the old class.
  • Misspelled or miscased class name — Java class names are case-sensitive and dotted exactly; com.mysql.jdbc.driver or org.postgresql.driver will not resolve.
  • Permissions on the JAR — the logstash service user cannot read the JAR (root-owned 0600 file), so the class fails to load even though the path is correct.
  • Corrupt or partial JAR download — a truncated connector JAR (interrupted curl, wrong artifact) does not contain the driver class.
  • Relative path resolved from the wrong working directoryjdbc_driver_library => "mysql-connector-j.jar" is resolved relative to Logstash’s runtime directory, not your config directory, and is not found.

Diagnostic Workflow

Start by validating that the configuration is syntactically sound. This does not load the driver, but it rules out a broken config file confusing the picture:

sudo -u logstash /usr/share/logstash/bin/logstash \
  -f /etc/logstash/conf.d/mysql-jdbc.conf \
  --config.test_and_exit --path.settings /etc/logstash

Then confirm the JAR actually exists, is readable by the service user, and contains the class you named:

# Does the file exist and can the logstash user read it?
sudo -u logstash test -r /usr/share/logstash/drivers/mysql-connector-j-8.4.0.jar && echo OK

# List the driver classes actually inside the JAR
unzip -l /usr/share/logstash/drivers/mysql-connector-j-8.4.0.jar | grep -i 'Driver.class'

For MySQL Connector/J 8.x you will see com/mysql/cj/jdbc/Driver.class — that dotted path (com.mysql.cj.jdbc.Driver) is exactly what belongs in jdbc_driver_class.

Here is a realistic, correct jdbc input block. Logstash .conf files use a Ruby-like DSL, so the config is shown as ruby:

input {
  jdbc {
    jdbc_driver_library => "/usr/share/logstash/drivers/mysql-connector-j-8.4.0.jar"
    jdbc_driver_class => "com.mysql.cj.jdbc.Driver"
    jdbc_connection_string => "jdbc:mysql://db.internal:3306/appdb?useSSL=false&serverTimezone=UTC"
    jdbc_user => "logstash_ro"
    jdbc_password => "${MYSQL_RO_PASSWORD}"

    schedule => "*/5 * * * *"
    statement => "SELECT id, email, updated_at FROM users WHERE updated_at > :sql_last_value"
    use_column_value => true
    tracking_column => "updated_at"
    tracking_column_type => "timestamp"
    last_run_metadata_path => "/var/lib/logstash/.jdbc_last_run_users"
  }
}

output {
  elasticsearch {
    hosts => ["https://es.internal:9200"]
    index => "app-users-%{+YYYY.MM.dd}"
    document_id => "%{id}"
  }
}

Finally, watch the log live while you start the pipeline so you catch the exact class name the JVM is missing:

sudo systemctl restart logstash
sudo tail -f /var/log/logstash/logstash-plain.log | grep -i 'ClassNotFound\|jdbc'

Example Root Cause Analysis

A team upgraded a Debian host and, as part of it, bumped the MySQL connector JAR from the old mysql-connector-java-5.1.47.jar to mysql-connector-j-8.4.0.jar. They updated jdbc_driver_library to the new path but left the rest of the block untouched. On restart the pipeline died immediately with ClassNotFoundException: com.mysql.jdbc.Driver.

The config was valid — --config.test_and_exit returned Configuration OK. So the syntax was not the problem. Running unzip -l on the new JAR was decisive:

$ unzip -l mysql-connector-j-8.4.0.jar | grep -i Driver.class
     1234  2024-04-25 10:12   com/mysql/cj/jdbc/Driver.class

The class shipped in 8.x is com.mysql.cj.jdbc.Driver — note the extra .cj. segment. The legacy com.mysql.jdbc.Driver was removed in Connector/J 8. The config still named the old class, so the JVM correctly reported it could not find it, even though a perfectly good driver JAR was on the classpath.

The fix was a one-line change:

# before
jdbc_driver_class => "com.mysql.jdbc.Driver"
# after
jdbc_driver_class => "com.mysql.cj.jdbc.Driver"

After restarting, logstash-plain.log showed the scheduled statement executing and rows flowing into the app-users-* index. The lesson: a passing config test only proves the syntax is valid; the driver class is verified against the JAR at runtime, so always confirm the class name matches what unzip -l reports inside the exact JAR you deployed.

Prevention Best Practices

  • Pin the connector JAR to an absolute, version-stamped path (/usr/share/logstash/drivers/mysql-connector-j-8.4.0.jar) and reference that same path in jdbc_driver_library — never a bare filename.
  • Whenever you upgrade a database connector, re-derive jdbc_driver_class from unzip -l …​ | grep Driver.class rather than copying it from an older config or a blog post.
  • Keep driver JARs owned by, and readable by, the logstash service user; store them outside the config directory so a config redeploy never removes them.
  • Use environment variables (${MYSQL_RO_PASSWORD}) for credentials via the Logstash keystore or ssr.env-style secrets, so the connection string in Git never carries a password.
  • Standardize on the current driver class per database: MySQL 8.x → com.mysql.cj.jdbc.Driver, PostgreSQL → org.postgresql.Driver, Oracle → oracle.jdbc.OracleDriver, SQL Server → com.microsoft.sqlserver.jdbc.SQLServerDriver.
  • Bake the JAR and its path into your image build or configuration-management role, and add a smoke test that greps the pipeline log for ClassNotFound after every deploy.

Quick Command Reference

# Validate config syntax (does not load the driver)
sudo -u logstash /usr/share/logstash/bin/logstash \
  -f /etc/logstash/conf.d/mysql-jdbc.conf \
  --config.test_and_exit --path.settings /etc/logstash

# List the actual driver classes inside a connector JAR
unzip -l /usr/share/logstash/drivers/mysql-connector-j-8.4.0.jar | grep -i 'Driver.class'

# Confirm the logstash user can read the JAR
sudo -u logstash test -r /usr/share/logstash/drivers/mysql-connector-j-8.4.0.jar && echo readable

# Watch for the exact missing-class error at startup
sudo tail -f /var/log/logstash/logstash-plain.log | grep -i 'ClassNotFound\|jdbc'

# Restart the service and follow status
sudo systemctl restart logstash && sudo systemctl status logstash --no-pager

Conclusion

ClassNotFoundException / could not load driver class from the Logstash jdbc input is almost always one of two things: the JAR named by jdbc_driver_library is missing or unreadable, or the name in jdbc_driver_class does not match the class that actually ships inside that JAR. Verify the file with test -r, list its classes with unzip -l, and set jdbc_driver_class to the exact dotted path you find — most often com.mysql.cj.jdbc.Driver for modern MySQL. Because driver loading happens at runtime rather than during --config.test_and_exit, always confirm the fix by tailing logstash-plain.log after a restart and watching the scheduled query run.

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.