{"record":{"id":"df23d6271d4071af","repo":"XINCGer/Unity3DTraining","slug":"mismatched-end-group-tag-started-with-field","errorCode":null,"errorMessage":"Mismatched end-group tag. Started with field ","messagePattern":"Mismatched end-group tag\\. Started with field ","errorType":"exception","errorClass":"InvalidProtocolBufferException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/CodedInputStream.cs","lineNumber":454,"sourceCode":"            {\n                tag = ReadTag();\n                if (tag == 0)\n                {\n                    throw InvalidProtocolBufferException.TruncatedMessage();\n                }\n                // Can't call SkipLastField for this case- that would throw.\n                if (WireFormat.GetTagWireType(tag) == WireFormat.WireType.EndGroup)\n                {\n                    break;\n                }\n                // This recursion will allow us to handle nested groups.\n                SkipLastField();\n            }\n            int startField = WireFormat.GetTagFieldNumber(startGroupTag);\n            int endField = WireFormat.GetTagFieldNumber(tag);\n            if (startField != endField)\n            {\n                throw new InvalidProtocolBufferException(\"Mismatched end-group tag. Started with field \" + startField + \"; ended with field \" + endField);\n            }\n            recursionDepth--;\n        }\n\n        /// <summary>\n        /// Reads a double field from the stream.\n        /// </summary>\n        public double ReadDouble()\n        {\n            return BitConverter.Int64BitsToDouble((long)ReadRawLittleEndian64());\n        }\n\n        /// <summary>\n        /// Reads a float field from the stream.\n        /// </summary>\n        public float ReadFloat()\n        {\n            if (BitConverter.IsLittleEndian && 4 <= bufferSize - bufferPos)","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/CodedInputStream.cs#L436-L472","documentation":"While skipping a group, SkipGroup reads tags until it finds the end-group tag; if the end-group tag's field number differs from the start-group tag's field number, the wire data is malformed and InvalidProtocolBufferException('Mismatched end-group tag...') is thrown. Groups (SGROUP/EGROUP) are legacy protobuf wire types where start and end must share a field number.","triggerScenarios":"Parsing bytes where an end-group tag for a different field number appears — due to corrupted data, desynchronized framing, mixing fields written by incompatible schemas, or manually crafted byte arrays.","commonSituations":"Legacy wire format data (proto2 groups) parsed with mismatched message definitions; byte offsets slipping after a partial read so a group-end tag is interpreted at the wrong position; concatenating serialized payloads incorrectly.","solutions":["Treat the payload as corrupt: catch InvalidProtocolBufferException, log the bytes, and drop or re-request the message.","Verify sender and receiver share the same .proto schema, especially any legacy group declarations.","Replace deprecated groups with nested messages in the schema if you control it.","Re-check framing logic so each parse starts exactly at a message boundary."],"exampleFix":"// before\ninput.SkipField(tag); // continues past mismatched group, corrupting state\n// after\ntry { input.SkipField(tag); }\ncatch (InvalidProtocolBufferException ex)\n{\n    logger.LogError(ex, \"Corrupt protobuf payload, dropping\");\n    return null;\n}","handlingStrategy":"try-catch","validationCode":"if (!Framing.IsAtMessageBoundary(stream)) await RefillBufferAsync(); // ensure aligned reads","typeGuard":"null","tryCatchPattern":"try { parser.ParseFrom(stream); } catch (InvalidProtocolBufferException ex) when (ex.Message.StartsWith(\"Mismatched end-group\")) { logger.LogError(ex, \"Corrupt group nesting; dropping payload of {N} bytes\", byteCount); metrics.Increment(\"protobuf_corrupt\"); return null; }","preventionTips":["Keep sender/receiver schemas identical; avoid legacy proto2 groups.","Catch InvalidProtocolBufferException at the transport boundary and reject the payload — never try to resynchronize mid-message.","Fuzz-test the parser with random/truncated byte arrays to verify it fails safely."],"tags":["protobuf","corrupt-data","wire-format"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"016f98412ea5e11756b286736f479b66ab6216d5","analyzedAt":"2026-09-12T01:08:58.711Z","contentChangedAt":"2026-09-12T01:08:58.711Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}