{"record":{"id":"001905d6ad2c5969","repo":"openzipkin/zipkin","slug":"invalid-span-expecting-annotations-array-start-g","errorCode":null,"errorMessage":"Invalid span, expecting annotations array start, got: {}","messagePattern":"Invalid span, expecting annotations array start, got: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/internal/JsonSerializers.java","lineNumber":88,"sourceCode":"          break;\n        case \"name\":\n          result.name(parser.getText());\n          break;\n        case \"timestamp\":\n          result.timestamp(parser.getLongValue());\n          break;\n        case \"duration\":\n          result.duration(parser.getLongValue());\n          break;\n        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;","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/internal/JsonSerializers.java#L70-L106","documentation":"Inside parseSpan, when the field name is 'annotations' the next token must be START_ARRAY ([...]); any other JSON type for that field throws IOException('Invalid span, expecting annotations array start, got: <token>'). The span format is strict: annotations is always an array of {timestamp,value} objects.","triggerScenarios":"A span document whose 'annotations' field is an object, string, number, or null-token shape other than an array — e.g. {\"traceId\":\"...\",\"annotations\":{\"ts\":1}} or annotations:\"none\" — reaching SPAN_PARSER from an index or test fixture.","commonSituations":"Hand-written JSON test fixtures; external systems writing spans directly into Zipkin's ES indices with a wrong schema; schema drift from custom ingest pipelines.","solutions":["Correct the document: annotations must be an array, e.g. \"annotations\":[{\"timestamp\":...,\"value\":\"...\"}].","Find who wrote the malformed docs (custom ingest job?) and fix its serializer to match the Zipkin span JSON schema.","Delete/reindex offending documents so queries stop hitting them.","When building spans in code, use Span.Builder.addAnnotation so the shape can never be wrong."],"exampleFix":"// before\n{\"traceId\":\"abc\",\"id\":\"def\",\"annotations\":{\"timestamp\":1,\"value\":\"sr\"}}\n// -> IOException: Invalid span, expecting annotations array start, got: VALUE_START_OBJECT/START_OBJECT\n\n// after\n{\"traceId\":\"abc\",\"id\":\"def\",\"annotations\":[{\"timestamp\":1470150004000000,\"value\":\"sr\"}]}","handlingStrategy":"type-guard","validationCode":"var span = objectMapper.readTree(spanJson);\nif (span.has(\"annotations\") && !span.get(\"annotations\").isArray()) {\n  throw new IOException(\"'annotations' must be an array of {timestamp,value} objects\");\n}","typeGuard":"boolean annotationsWellFormed(JsonNode span) {\n  JsonNode a = span.get(\"annotations\");\n  return a == null || (a.isArray() && a.allMatch(e -> e.isObject() && e.has(\"timestamp\") && e.has(\"value\")));\n}","tryCatchPattern":"try { Span s = SPAN_PARSER.parse(p); }\ncatch (IOException e) {\n  if (e.getMessage().startsWith(\"Invalid span, expecting annotations array start\")) {\n    // reject the document; fix the producer's serializer\n  }\n}","preventionTips":["Always emit annotations as [{timestamp, value}] — arrays of objects, never maps or strings.","Build spans with Span.Builder.addAnnotation so serialization is correct by construction.","Add schema validation in custom ingest pipelines writing to Zipkin indices."],"tags":["elasticsearch","json-parsing","span","schema","deserialization"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}