openzipkin/zipkin · error · NullPointerException
key == null
Error message
key == null
What it means
MySQLAutocompleteTags.getValues(key) runs a SelectAutocompleteValues query against the zipkin_annotations table for a configured autocomplete key. The API requires a non-null, non-empty key; null fails fast with NullPointerException('key == null') before any SQL is built. Unlike the Elasticsearch variant, it also requires the key to be in the configured autocompleteKeys set or it returns an empty list.
Source
Thrown at zipkin-storage/mysql-v1/src/main/java/zipkin2/storage/mysql/v1/MySQLAutocompleteTags.java:33
final boolean enabled;
final LinkedHashSet<String> autocompleteKeys;
final Call<List<String>> keysCall;
MySQLAutocompleteTags(MySQLStorage storage, Schema schema) {
this.dataSourceCallFactory = storage.dataSourceCallFactory;
this.schema = schema;
enabled = storage.searchEnabled && !storage.autocompleteKeys.isEmpty();
autocompleteKeys = new LinkedHashSet<>(storage.autocompleteKeys);
keysCall = Call.create(storage.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 || !autocompleteKeys.contains(key)) return Call.emptyList();
return dataSourceCallFactory.create(new SelectAutocompleteValues(schema, key));
}
}
View on GitHub (pinned to 878ce2a1fa)
Solutions
- Fix the caller to pass a non-null key; find where the null originates (usually an unchecked request parameter).
- Validate input at your API boundary: reject or return empty for missing keys.
- Remember the key must also be listed in storage.autocompleteKeys to return data.
Example fix
// before
String key = request.getParameter("key");
Call<List<String>> values = storage.autocompleteTags().getValues(key); // NPE when param absent
// 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 respond 400 for a required param
}
Call<List<String>> values = storage.autocompleteTags().getValues(key); Type guard
static boolean isQueryableKey(String key) {
return key != null && !key.isEmpty();
} Prevention
- Validate the key parameter at your HTTP boundary before calling the store.
- Remember MySQL only returns values for keys configured in autocompleteKeys.
- Add unit tests covering null/empty key paths in any wrapper you build.
When it happens
Trigger: Calling autocompleteTags().getValues(null) on MySQLStorage, typically by forwarding a missing/unvalidated request parameter straight from an HTTP endpoint.
Common situations: Custom REST facades or UIs over MySQLStorage where ?key= is optional and not checked; refactors that introduce null paths; tests passing null.
Related errors
AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14).
Data as JSON: /api/errors/3f73f8584501f987.
Report an issue: GitHub.