openzipkin/zipkin · error · NullPointerException
key == null
Error message
key == null
What it means
ElasticsearchAutocompleteTags.getValues(key) fetches distinct values for an autocomplete tag key within the names lookback window. The API contract requires a non-null, non-empty key; null fails fast with NullPointerException('key == null') before any query is built. This is a programmer-error guard, not an environmental failure.
Source
Thrown at zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/ElasticsearchAutocompleteTags.java:39
final SearchCallFactory search;
final int namesLookback;
final Call<List<String>> keysCall;
ElasticsearchAutocompleteTags(ElasticsearchStorage es) {
this.search = new SearchCallFactory(es.http());
this.indexNameFormatter = es.indexNameFormatter();
this.enabled = es.searchEnabled() && !es.autocompleteKeys().isEmpty();
this.namesLookback = es.namesLookback();
this.keysCall = Call.create(es.autocompleteKeys());
}
@Override public Call<List<String>> getKeys() {
if (!enabled) return Call.emptyList();
return keysCall.clone();
}
@Override public Call<List<String>> getValues(String key) {
if (key == null) throw new NullPointerException("key == null");
if (key.isEmpty()) throw new IllegalArgumentException("key was empty");
if (!enabled) return Call.emptyList();
long endMillis = System.currentTimeMillis();
long beginMillis = endMillis - namesLookback;
List<String> indices =
indexNameFormatter.formatTypeAndRange(TYPE_AUTOCOMPLETE, beginMillis, endMillis);
if (indices.isEmpty()) return Call.emptyList();
SearchRequest.Filters filters =
new SearchRequest.Filters().addTerm("tagKey", key);
SearchRequest request = SearchRequest.create(indices)
.filters(filters)
.addAggregation(Aggregation.terms("tagValue", Integer.MAX_VALUE));
return search.newCall(request, BodyConverters.KEYS);
}View on GitHub (pinned to 878ce2a1fa)
Solutions
- Fix the caller to pass a non-null key; trace where the null originates (often an unchecked request parameter).
- Validate at the boundary: reject or skip requests with a missing key before reaching storage.
- If the key is optional in your API, return an empty list instead of calling getValues.
Example fix
// before
String key = request.getParameter("key"); // may be null
Call<List<String>> values = storage.autocompleteTags().getValues(key); // NPE
// after
String key = request.getParameter("key");
if (key == null || key.isEmpty()) return Collections.emptyList();
Call<List<String>> values = storage.autocompleteTags().getValues(key); Defensive patterns
Strategy: validation
Validate before calling
if (key == null || key.isEmpty()) {
return Collections.emptyList(); // or reject the request with 400
} Type guard
static boolean isQueryableKey(String key) {
return key != null && !key.isEmpty();
} Prevention
- Validate request parameters at the HTTP boundary before touching the SpanStore API.
- Treat autocomplete keys like required query params: reject with 400, never forward null.
- Cover getValues(null) with a unit test asserting the NPE contract if you wrap this API.
When it happens
Trigger: Calling autocompleteTags().getValues(null) on ElasticsearchStorage, typically because a caller forwarded an unvalidated request parameter (e.g. a missing ?key= query param from an HTTP API) straight into getValues.
Common situations: Building a custom UI or REST facade over the SpanStore API where the key arrives from user input and optional parameters are not filtered; refactoring that introduces a null path; tests that pass null by accident.
Related errors
- key == null
- key == null
- keys == null
- Invalid .version.number: %s, for .version.distribution:%s
- endTs <= 0
AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14).
Data as JSON: /api/errors/1357c6fefc107f3a.
Report an issue: GitHub.