openzipkin/zipkin · error · IOException

Invalid span, expecting tags object, got: {}

Error message

Invalid span, expecting tags object, got: {}

What it means

In parseSpan, the 'tags' field must be a JSON object (START_OBJECT); any other shape (array, string, number) throws IOException('Invalid span, expecting tags object, got: <token>'). Tags are key/value pairs, and the parser then reads each entry with parser.nextValue() until END_OBJECT.

Source

Thrown at zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/internal/JsonSerializers.java:98

        case "localEndpoint":
          result.localEndpoint(parseEndpoint(parser));
          break;
        case "remoteEndpoint":
          result.remoteEndpoint(parseEndpoint(parser));
          break;
        case "annotations":
          if (value != JsonToken.START_ARRAY) {
            throw new IOException("Invalid span, expecting annotations array start, got: " +
              value);
          }
          while (parser.nextToken() != JsonToken.END_ARRAY) {
            Annotation a = parseAnnotation(parser);
            result.addAnnotation(a.timestamp(), a.value());
          }
          break;
        case "tags":
          if (value != JsonToken.START_OBJECT) {
            throw new IOException("Invalid span, expecting tags object, got: " + value);
          }
          while (parser.nextValue() != JsonToken.END_OBJECT) {
            result.putTag(parser.currentName(), parser.getValueAsString());
          }
          break;
        case "debug":
          result.debug(parser.getBooleanValue());
          break;
        case "shared":
          result.shared(parser.getBooleanValue());
          break;
        default:
          // Skip
      }
    }

    return result.build();
  }

View on GitHub (pinned to 878ce2a1fa)

Solutions

  1. Fix the document: tags must be an object, e.g. "tags":{"http.path":"/api"}.
  2. Fix the producing serializer (custom collector/ETL) to emit tags as a JSON map.
  3. Reindex or delete malformed documents in the affected indices.
  4. Build spans via Span.Builder.putTag in your own code so the encoding is always correct.

Example fix

// before
{"traceId":"abc","id":"def","tags":[{"key":"http.path","value":"/api"}]}
// -> IOException: Invalid span, expecting tags object, got: START_ARRAY

// after
{"traceId":"abc","id":"def","tags":{"http.path":"/api"}}
Defensive patterns

Strategy: type-guard

Validate before calling

var span = objectMapper.readTree(spanJson);
if (span.has("tags") && !span.get("tags").isObject()) {
  throw new IOException("'tags' must be a JSON object of name/value pairs");
}

Type guard

boolean tagsWellFormed(JsonNode span) {
  JsonNode t = span.get("tags");
  return t == null || t.isObject();
}

Try / catch

try { Span s = SPAN_PARSER.parse(p); }
catch (IOException e) {
  if (e.getMessage().startsWith("Invalid span, expecting tags object")) {
    // reject the document; fix the producer emitting tags as arrays/scalars
  }
}

Prevention

When it happens

Trigger: A span document with "tags":["http.path"] or "tags":"none" — tags encoded as an array or scalar instead of an object map — being parsed by SPAN_PARSER.

Common situations: Custom ingest pipelines or fixtures encoding tags differently; converting from other trace formats (some use arrays of {k,v}); documents written into Zipkin indices by third-party tools.

Related errors


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