{"record":{"id":"a85e5d7cc5cab633","repo":"zaproxy/zaproxy","slug":"db-class-is-not-an-instance-of-database","errorCode":null,"errorMessage":"db.class is not an instance of Database: ","messagePattern":"db\\.class is not an instance of Database: ","errorType":"exception","errorClass":"DatabaseException","httpStatus":null,"severity":"error","filePath":"zap/src/main/java/org/zaproxy/zap/db/sql/DbSQL.java","lineNumber":149,"sourceCode":"        try (Reader sqlReader = new FileReader(sqlFile)) {\n            sqlProperties.load(sqlReader);\n        } catch (Exception e) {\n            LOGGER.error(\"No SQL properties file for db type {}\", sqlFile.getAbsolutePath());\n            throw new DatabaseException(\n                    \"Missing SQL properties file: \" + sqlFile.getAbsolutePath());\n        }\n\n        String className = dbProperties.getProperty(\"db.class\");\n        Object dbObj;\n        try {\n            Class<?> dbClass = Class.forName(className);\n            dbObj = dbClass.getDeclaredConstructor().newInstance();\n        } catch (Exception e) {\n            throw new DatabaseException(\"Failed to create the instance for: \" + className, e);\n        }\n\n        if (!(dbObj instanceof Database)) {\n            throw new DatabaseException(\n                    \"db.class is not an instance of Database: \"\n                            + dbObj.getClass().getCanonicalName());\n        }\n        return (Database) dbObj;\n    }\n\n    public static void addSqlProperties(InputStream inStream) throws IOException {\n        sqlProperties.load(inStream);\n    }\n\n    public static String getSQL(String key) {\n        String str = sqlProperties.getProperty(key);\n        if (str != null) {\n            // trailing spaces can cause havoc ;)\n            str = str.trim();\n        }\n        return str;\n    }","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/zaproxy/zaproxy/blob/9d1970a436b1b189bfb588fc88864c80d9baf6a5/zap/src/main/java/org/zaproxy/zap/db/sql/DbSQL.java#L131-L167","documentation":"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.","triggerScenarios":"initDatabase() instantiates the db.class value and runs `if (!(dbObj instanceof Database))` — triggered whenever db.class points to any class not implementing Database.","commonSituations":"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.","solutions":["Set db.class in db.properties to a class that implements org.parosproxy.paros.db.Database (e.g. the shipped SqlDatabase implementation).","If it's a custom implementation, make it implement the Database interface (and its table methods).","After a ZAP upgrade, check for interface renames/repackaging and update the custom class's implements clause and the config value."],"exampleFix":"// before\npublic class MyDb { /* no Database interface */ }\n// after\npublic class MyDb implements org.parosproxy.paros.db.Database { ... }","handlingStrategy":"validation","validationCode":"Class<?> c = Class.forName(props.getProperty(\"db.class\"));\nif (!org.parosproxy.paros.db.Database.class.isAssignableFrom(c)) {\n    throw new IllegalStateException(c.getName() + \" does not implement Database\");\n}","typeGuard":"boolean isValidDatabaseClass(Class<?> c) {\n    return c != null && org.parosproxy.paros.db.Database.class.isAssignableFrom(c);\n}","tryCatchPattern":"try {\n    initDatabase();\n} catch (DatabaseException e) {\n    // message names the offending class; fix db.class or implement Database\n    LOGGER.error(\"db.class does not implement Database: {}\", e.getMessage());\n}","preventionTips":["Point db.class only at classes implementing org.parosproxy.paros.db.Database","Compile custom DB classes against the same ZAP version's Database interface","Re-check implements clauses after ZAP API upgrades"],"tags":["java","database","configuration","type-check"],"backgroundTag":"type-mismatch","analyzedSha":"9d1970a436b1b189bfb588fc88864c80d9baf6a5","analyzedAt":"2026-09-05T19:26:59.356Z","contentChangedAt":"2026-09-05T19:26:59.356Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}