{"record":{"id":"51f449f06e06d26d","repo":"openzipkin/zipkin","slug":"invalid-span-expecting-tags-object-got","errorCode":null,"errorMessage":"Invalid span, expecting tags object, got: {}","messagePattern":"Invalid span, expecting tags object, got: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/internal/JsonSerializers.java","lineNumber":98,"sourceCode":"        case \"localEndpoint\":\n          result.localEndpoint(parseEndpoint(parser));\n          break;\n        case \"remoteEndpoint\":\n          result.remoteEndpoint(parseEndpoint(parser));\n          break;\n        case \"annotations\":\n          if (value != JsonToken.START_ARRAY) {\n            throw new IOException(\"Invalid span, expecting annotations array start, got: \" +\n              value);\n          }\n          while (parser.nextToken() != JsonToken.END_ARRAY) {\n            Annotation a = parseAnnotation(parser);\n            result.addAnnotation(a.timestamp(), a.value());\n          }\n          break;\n        case \"tags\":\n          if (value != JsonToken.START_OBJECT) {\n            throw new IOException(\"Invalid span, expecting tags object, got: \" + value);\n          }\n          while (parser.nextValue() != JsonToken.END_OBJECT) {\n            result.putTag(parser.currentName(), parser.getValueAsString());\n          }\n          break;\n        case \"debug\":\n          result.debug(parser.getBooleanValue());\n          break;\n        case \"shared\":\n          result.shared(parser.getBooleanValue());\n          break;\n        default:\n          // Skip\n      }\n    }\n\n    return result.build();\n  }","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/internal/JsonSerializers.java#L80-L116","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fix the document: tags must be an object, e.g. \"tags\":{\"http.path\":\"/api\"}.","Fix the producing serializer (custom collector/ETL) to emit tags as a JSON map.","Reindex or delete malformed documents in the affected indices.","Build spans via Span.Builder.putTag in your own code so the encoding is always correct."],"exampleFix":"// before\n{\"traceId\":\"abc\",\"id\":\"def\",\"tags\":[{\"key\":\"http.path\",\"value\":\"/api\"}]}\n// -> IOException: Invalid span, expecting tags object, got: START_ARRAY\n\n// after\n{\"traceId\":\"abc\",\"id\":\"def\",\"tags\":{\"http.path\":\"/api\"}}","handlingStrategy":"type-guard","validationCode":"var span = objectMapper.readTree(spanJson);\nif (span.has(\"tags\") && !span.get(\"tags\").isObject()) {\n  throw new IOException(\"'tags' must be a JSON object of name/value pairs\");\n}","typeGuard":"boolean tagsWellFormed(JsonNode span) {\n  JsonNode t = span.get(\"tags\");\n  return t == null || t.isObject();\n}","tryCatchPattern":"try { Span s = SPAN_PARSER.parse(p); }\ncatch (IOException e) {\n  if (e.getMessage().startsWith(\"Invalid span, expecting tags object\")) {\n    // reject the document; fix the producer emitting tags as arrays/scalars\n  }\n}","preventionTips":["Emit tags as a JSON map {\"key\":\"value\"}.","Use Span.Builder.putTag in producers instead of hand-writing tag JSON.","Validate converted payloads from other trace formats before indexing them."],"tags":["elasticsearch","json-parsing","span","tags","schema"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}