openzipkin/zipkin · error · IllegalArgumentException

No value at {}

Error message

No value at {}

What it means

In V2 JSON spans the "tags" member is an object mapping tag names to string values. When a tag's value is JSON null, V2SpanReader throws 'No value at <jsonPath>' — null is not a valid tag value because tags are plain strings (empty string is allowed, null is not).

Source

Thrown at zipkin/src/main/java/zipkin2/internal/V2SpanReader.java:79

            } else if (nextName.equals("value")) {
              value = reader.nextString();
            } else {
              reader.skipValue();
            }
          }
          if (timestamp == null || value == null) {
            throw new IllegalArgumentException("Incomplete annotation at " + reader.getPath());
          }
          reader.endObject();
          builder.addAnnotation(timestamp, value);
        }
        reader.endArray();
      } else if (nextName.equals("tags")) {
        reader.beginObject();
        while (reader.hasNext()) {
          String key = reader.nextName();
          if (reader.peekNull()) {
            throw new IllegalArgumentException("No value at " + reader.getPath());
          }
          builder.putTag(key, reader.nextString());
        }
        reader.endObject();
      } else if (nextName.equals("debug")) {
        if (reader.nextBoolean()) builder.debug(true);
      } else if (nextName.equals("shared")) {
        if (reader.nextBoolean()) builder.shared(true);
      } else {
        reader.skipValue();
      }
    }
    reader.endObject();
    return builder.build();
  }

  @Override public String toString() {
    return "Span";

View on GitHub (pinned to 878ce2a1fa)

Solutions

  1. On the producer, filter null values before tagging: tags.forEach((k,v) -> { if (v != null) span.tag(k, v); });
  2. Configure Jackson/Gson serializers with NON_NULL inclusion so null map values are not emitted.
  3. Represent absence by omitting the tag entirely, never by a null value; use "" if an empty tag is intended.
  4. At ingest, pre-parse and strip null tag values if you must accept dirty payloads.

Example fix

// before
Map<String,String> meta = ...; // may contain nulls
meta.forEach(span::tag);

// after
for (Map.Entry<String,String> e : meta.entrySet()) {
  if (e.getValue() != null) span.tag(e.getKey(), e.getValue());
}
Defensive patterns

Strategy: validation

Validate before calling

for (Map.Entry<String,String> e : metadata.entrySet()) { if (e.getValue() != null) span.tag(e.getKey(), e.getValue()); }

Type guard

boolean tagValuePresent(JsonNode tags, String key) { return tags.has(key) && !tags.get(key).isNull(); }

Prevention

When it happens

Trigger: SpanBytesDecoder.JSON_V2 decoding a span like {"tags":{"env":null}} — typically produced by serializing a map that contains a null value, or by mappers that emit null for missing entries.

Common situations: Reporters copying application maps into tags verbatim (HashMap with null values); JSON serializers not configured to exclude nulls; middleware adding conditional tags and writing null when a condition is false.

Related errors


AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14). Data as JSON: /api/errors/1283f418ae69efbe. Report an issue: GitHub.