Sgctl java.lang.NullPointerException

Why there is nullpointer exception when you update configuration? I noticed that you build configuration, then maybe change something in the sg_* files and everytime you try to update there is java nullpointer. The only time I am not getting it its the first time, after that I have to use --force parameter to get config update.

if you run ./sgctl.sh get-config -o test and then ./sgctl.sh update-config ./test then all is good, but if you execute it again the same code no changes you get exception again.

{"type": "server", "timestamp": "2022-09-16T15:39:45,029+02:00", "level": "WARN", "component": "r.suppressed", "cluster.name": "test", "node.name": "test-test01-1", "message": "path: /_searchguard/config, params: {}", "cluster.uuid": "2MquIlKOThW5qCFrcWvpPQ", "node.id": "dTnKWnR8Q0yYaZSQ66JsVQ" , 
"stacktrace": ["java.util.concurrent.CompletionException: java.lang.NullPointerException",
"at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:314) ~[?:?]",
"at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:319) [?:?]",
"at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1702) [?:?]",
"at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingRunnable.run(ThreadContext.java:718) [elasticsearch-7.17.6.jar:7.17.6]",
"at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]",
"at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]",
"at java.lang.Thread.run(Thread.java:829) [?:?]",
"Caused by: java.lang.NullPointerException",
"at com.floragunn.searchsupport.action.StandardResponse.data(StandardResponse.java:85) ~[?:?]",
"at com.floragunn.searchguard.configuration.api.BulkConfigApi$UpdateAction$Handler.lambda$doExecute$0(BulkConfigApi.java:271) ~[?:?]",
"at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700) ~[?:?]",
"... 4 more"] }

Is it intended to use it always with --force param when updating all at once ?

What is the point of those tags at the beginning of the file ? If I delete them it works ok.

# sg_tenants v:1.0.0 cluster:test etag:1.922

Hi Peter,

thank you for the report. This seems to be a bug; I filed an issue in our Gitlab repo. You can track it at NPE in BulkConfigApi$UpdateAction (#118) · Issues · search-guard / Search Guard Suite Enterprise · GitLab

May I also ask for the version of Elasticsearch you are using?

Some background:

The header in the file you are mentioning contains the version of the configuration document at the time it was retrieved (this is etag:1.922). This is used to recognize version conflicts during updates.

Consider the following example:

  • User A retrieves the configuration to their local computer.
  • User A makes modifications to the configuration and uploads it again to the cluster
  • User B retrieves the configuration to their local computer as well.
  • User B modifies it as well and uploads to again to the cluster
  • User A continues to use the local copy, makes further modifications and uploads it. If no versioning check is performed, user A will now overwrite the modifications done by user B.

Because of this reason, Search Guard and sgctl will now always write the header with the version information. If Search Guard detects that a user tries to upload a configuration that has been also modified on the cluster, it will warn about that. At least, it is supposed to do so. The exception you are observing might obscure the warning.

However, there are situations where you do not care for the version of the configuration on the cluster. In these cases, you can either use sgctl with the --force switch or delete the etag:* information from the file header.

Hope that clarifies it a bit.

Hi Nils, ok it make sense, thanks. In our case we don’t care so much about concurrent updates, because it can’t happen due to configuration deployment design, but good to know it is there.

THanks, P.