{"record":{"id":"9ce598e8cd11ff6f","repo":"NationalSecurityAgency/ghidra","slug":"trying-to-insert-on-read-only-database-9ce598","errorCode":null,"errorMessage":"Trying to insert on read-only database","messagePattern":"Trying to insert on read-only database","errorType":"validation","errorClass":"LSHException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java","lineNumber":3041,"sourceCode":"\t * @param request is command parameters\n\t */\n\tprivate void fdbPrewarm(PrewarmRequest request) {\n\t\tfinal ResponsePrewarm response = request.prewarmresponse;\n\t\tresponse.operationSupported = false;\n\t}\n\n\t/**\n\t * Entry point for the Elasticsearch version of InsertRequest command:\n\t *   Insert new functions and executables into the database.\n\t * @param query is command parameters\n\t * @throws LSHException if the command is misconfigured\n\t * @throws ElasticException for communication problems with the server\n\t * @throws DatabaseNonFatalException if everything is already inserted\n\t */\n\tprivate void fdbDatabaseInsert(InsertRequest query)\n\t\t\tthrows LSHException, ElasticException, DatabaseNonFatalException {\n\t\tif (info.readonly) {\n\t\t\tthrow new LSHException(\"Trying to insert on read-only database\");\n\t\t}\n\t\tif (FunctionDatabase.checkSettingsForInsert(query.manage, info)) { // Check if settings are valid and is this is first insert\n\t\t\tinfo.major = query.manage.getMajorVersion();\n\t\t\tinfo.minor = query.manage.getMinorVersion();\n\t\t\tinfo.settings = query.manage.getSettings();\n\t\t\twriteBasicInfo(0, 0); // Save off the settings associated with this first insert\n\t\t}\n\t\tResponseInsert response = query.insertresponse;\n\t\tif ((query.repo_override != null) && (query.repo_override.length() != 0)) {\n\t\t\tquery.manage.overrideRepository(query.repo_override, query.path_override);\n\t\t}\n\t\t// Insert each executable in turn\n\t\tboolean newExecutable = false;\n\t\tfor (ExecutableRecord erec : query.manage.getExecutableRecordSet()) {\n\t\t\tif (erec.isLibrary()) {\n\t\t\t\tinsertLibrary(query.manage, erec);\n\t\t\t}\n\t\t\telse if (insertExe(query.manage, erec)) {","sourceCodeStart":3023,"sourceCodeEnd":3059,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java#L3023-L3059","documentation":"fdbDatabaseInsert first checks info.readonly; if the database was opened read-only it throws LSHException(\"Trying to insert on read-only database\") before any insert is attempted.","triggerScenarios":"Issuing an InsertRequest against a connection/database that was opened in read-only mode.","commonSituations":"Connecting with a read-only URL or read-only credential to perform ingest; pointing at a read replica; forgot to set write mode.","solutions":["Open the database in read/write mode.","Use write-enabled credentials / a write-capable URL.","Perform inserts against the primary cluster, not a read replica."],"exampleFix":"// before\n// opened readonly: db.initializeReadOnly(url); db.insert(req); -> LSHException\n// after\ndb.initialize(url); // read/write\ndb.insert(req);","handlingStrategy":"validation","validationCode":"if (db.getInfo().readonly) {\n    throw new IllegalStateException(\"Database is read-only; cannot insert\");\n}","typeGuard":"boolean writable = !db.getInfo().readonly;","tryCatchPattern":null,"preventionTips":["Open a separate read/write handle for ingest paths.","Gate ingest commands on a writable-connection check."],"tags":["bsim","readonly","permissions","ingestion"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}