{"record":{"id":"eace41d64521b599","repo":"NationalSecurityAgency/ghidra","slug":"reason","errorCode":null,"errorMessage":"reason","messagePattern":"reason","errorType":"exception","errorClass":"ElasticException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java","lineNumber":198,"sourceCode":"\t\tif (catrecs != null) {\n\t\t\tbuilder.append(\", \");\n\t\t\tappendCategoryTag(catrecs, builder);\n\t\t}\n\t\tbuilder.append(\", \\\"join_field\\\": \\\"exe\\\" }\");\n\t\tStringBuilder pathbuilder = new StringBuilder();\n\t\tpathbuilder.append(\"executable/_doc/\");\n\t\tpathbuilder.append(exeId);\n\t\tpathbuilder.append(\"?op_type=create\");\t\t// Do \"create\" operation, so we fail if document already exists\n\t\tJsonObject resp = connection.executeStatementExpectFailure(ElasticConnection.PUT,\n\t\t\tpathbuilder.toString(), builder.toString());\n\t\tJsonObject error = (JsonObject) resp.get(\"error\");\n\t\tif (error != null) {\n\t\t\tString type = error.get(\"type\").getAsString();\n\t\t\tif (type.startsWith(\"version_conflict\")) {\n\t\t\t\treturn false;\t\t\t// Document already inserted\n\t\t\t}\n\t\t\tString reason = ElasticConnection.convertToString(error.get(\"reason\"));\n\t\t\tthrow new ElasticException(reason);\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Set the \"document id\" for an ExecutableRecord. This is currently the\n\t * last 96-bits of the md5 hash of the executable encoded in base64\n\t * @param manager is the container for the ExecutableRecord\n\t * @param exeRecord has its key set\n\t * @return the new RowKey\n\t */\n\tprivate static RowKeyElastic updateKey(DescriptionManager manager, ExecutableRecord exeRecord) {\n\t\tif (exeRecord.getRowId() == null) {\n\t\t\tRowKeyElastic eKey = new RowKeyElastic(exeRecord.getMd5());\n\t\t\tmanager.setExeRowId(exeRecord, eKey);\n\t\t\treturn eKey;\n\t\t}\n\t\treturn (RowKeyElastic) exeRecord.getRowId();","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java#L180-L216","documentation":"In insertExecutableRecord the executable document is PUT with op_type=create; a version_conflict error type is tolerated (means 'already exists' -> return false). Any OTHER error in the ES response causes an ElasticException carrying the raw 'reason' string from the Elasticsearch error JSON. So the message text is whatever Elasticsearch reported.","triggerScenarios":"Creating an executable document whose response error type is not a version_conflict: mapper/parsing error, cluster read-only block, malformed JSON body, index-mapping conflict, or a connectivity error surfaced as an error envelope.","commonSituations":"ES cluster pushed to read_only_allow_indices by disk flood-stage watermark; version skew between client expectations and server; mapping explosion after schema drift; transient 5xx returned as an error blob.","solutions":["Read the 'reason' string -- it is the verbatim Elasticsearch message -- and address that root cause.","Check cluster health and readonly blocks: GET _cluster/settings; clear index.blocks.read_only_allow_write if set (flood-stage disk watermark).","Verify the executable document JSON and index mapping are well-formed and consistent.","Confirm ES server version compatibility with the BSim client."],"exampleFix":"// before\n// unhandled: the raw ES reason bubbles up opaquely\n// after\ntry {\n    db.insert(req);\n} catch (ElasticException e) {\n    if (e.getMessage().contains(\"read_only_allow_indices\")) {\n        clearReadOnlyBlock(db.getDatabaseName());\n        // retry once\n    } else {\n        throw e;\n    }\n}","handlingStrategy":"try-catch","validationCode":"// Cheap pre-flight: cluster must be writable.\nif (cluster.hasReadOnlyBlock(dbName)) {\n    throw new IllegalStateException(\"Cluster is read-only; cannot ingest\");\n}","typeGuard":null,"tryCatchPattern":"// Inspect the ES reason; retry only on transient/readonly causes.\ntry {\n    db.insert(req);\n} catch (ElasticException e) {\n    String r = e.getMessage();\n    if (r.contains(\"read_only\") || r.contains(\"timeout\")) { retry(req); }\n    else throw e;\n}","preventionTips":["Monitor ES disk watermarks so the cluster never flips to read_only mid-ingest.","Keep the BSim client and ES server on a compatible major version.","Validate JSON bodies locally before large bulks."],"tags":["bsim","elasticsearch","cluster","mapping"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}