zaproxy/zaproxy · error · DatabaseException

db.class is not an instance of Database:

Error message

db.class is not an instance of Database: 

What it means

Thrown by DbSQL.initDatabase() after successful reflective instantiation when the object created from db.class does not implement the org.parosproxy.paros.db.Database interface. This guards against configuring an arbitrary class as the database implementation. No cause is chained; the message names the offending class.

Source

Thrown at zap/src/main/java/org/zaproxy/zap/db/sql/DbSQL.java:149

        try (Reader sqlReader = new FileReader(sqlFile)) {
            sqlProperties.load(sqlReader);
        } catch (Exception e) {
            LOGGER.error("No SQL properties file for db type {}", sqlFile.getAbsolutePath());
            throw new DatabaseException(
                    "Missing SQL properties file: " + sqlFile.getAbsolutePath());
        }

        String className = dbProperties.getProperty("db.class");
        Object dbObj;
        try {
            Class<?> dbClass = Class.forName(className);
            dbObj = dbClass.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new DatabaseException("Failed to create the instance for: " + className, e);
        }

        if (!(dbObj instanceof Database)) {
            throw new DatabaseException(
                    "db.class is not an instance of Database: "
                            + dbObj.getClass().getCanonicalName());
        }
        return (Database) dbObj;
    }

    public static void addSqlProperties(InputStream inStream) throws IOException {
        sqlProperties.load(inStream);
    }

    public static String getSQL(String key) {
        String str = sqlProperties.getProperty(key);
        if (str != null) {
            // trailing spaces can cause havoc ;)
            str = str.trim();
        }
        return str;
    }

View on GitHub (pinned to 9d1970a436)

Solutions

  1. Set db.class in db.properties to a class that implements org.parosproxy.paros.db.Database (e.g. the shipped SqlDatabase implementation).
  2. If it's a custom implementation, make it implement the Database interface (and its table methods).
  3. After a ZAP upgrade, check for interface renames/repackaging and update the custom class's implements clause and the config value.

Example fix

// before
public class MyDb { /* no Database interface */ }
// after
public class MyDb implements org.parosproxy.paros.db.Database { ... }
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = Class.forName(props.getProperty("db.class"));
if (!org.parosproxy.paros.db.Database.class.isAssignableFrom(c)) {
    throw new IllegalStateException(c.getName() + " does not implement Database");
}

Type guard

boolean isValidDatabaseClass(Class<?> c) {
    return c != null && org.parosproxy.paros.db.Database.class.isAssignableFrom(c);
}

Try / catch

try {
    initDatabase();
} catch (DatabaseException e) {
    // message names the offending class; fix db.class or implement Database
    LOGGER.error("db.class does not implement Database: {}", e.getMessage());
}

Prevention

When it happens

Trigger: initDatabase() instantiates the db.class value and runs `if (!(dbObj instanceof Database))` — triggered whenever db.class points to any class not implementing Database.

Common situations: db.class in db.properties edited to an unrelated class name; custom class implementing the wrong/old Database interface after an API refactor; copy-paste of a class name from a different subsystem.

Related errors


AI-assisted analysis of zaproxy/zaproxy@9d1970a436 (2026-09-05). Data as JSON: /api/errors/a85e5d7cc5cab633. Report an issue: GitHub.