{"record":{"id":"9eee96d0f7fcb25b","repo":"temporalio/temporal","slug":"unmarshal-payload-for-queue-with-type-v-and-name","errorCode":null,"errorMessage":"unmarshal payload for queue with type %v and name %v failed: %w","messagePattern":"unmarshal payload for queue with type (.+?) and name (.+?) failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/persistence/sql/queue_v2.go","lineNumber":364,"sourceCode":"\t}\n\treturn q.extractQueueMetadata(metadata)\n}\n\nfunc (q queueV2) extractQueueMetadata(metadataRow *sqlplugin.QueueV2MetadataRow) (*persistencespb.Queue, error) {\n\tif metadataRow.MetadataEncoding != enumspb.ENCODING_TYPE_PROTO3.String() {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"queue with type %v and name %v has invalid encoding: %w\",\n\t\t\tmetadataRow.QueueType,\n\t\t\tmetadataRow.QueueName,\n\t\t\tserialization.NewUnknownEncodingTypeError(metadataRow.MetadataEncoding, enumspb.ENCODING_TYPE_PROTO3),\n\t\t)\n\t}\n\tqm := &persistencespb.Queue{}\n\terr := qm.Unmarshal(metadataRow.MetadataPayload)\n\tif err != nil {\n\t\treturn nil, serialization.NewDeserializationError(\n\t\t\tenumspb.ENCODING_TYPE_PROTO3,\n\t\t\tfmt.Errorf(\"unmarshal payload for queue with type %v and name %v failed: %w\",\n\t\t\t\tmetadataRow.QueueType,\n\t\t\t\tmetadataRow.QueueName,\n\t\t\t\terr),\n\t\t)\n\t}\n\treturn qm, nil\n}\n\nfunc (q *queueV2) getMaxMessageID(ctx context.Context, queueType persistence.QueueV2Type, queueName string, tc sqlplugin.TableCRUD) (int64, bool, error) {\n\tlastMessageID, err := tc.GetLastEnqueuedMessageIDForUpdateV2(ctx, sqlplugin.QueueV2Filter{\n\t\tQueueType: queueType,\n\t\tQueueName: queueName,\n\t\tPartition: defaultPartition,\n\t})\n\tswitch {\n\tcase err == nil:\n\t\treturn lastMessageID, true, nil\n\tcase errors.Is(err, sql.ErrNoRows):","sourceCodeStart":346,"sourceCodeEnd":382,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/persistence/sql/queue_v2.go#L346-L382","documentation":"After the encoding check passes, extractQueueMetadata unmarshals the metadata payload blob into persistencespb.Queue. A protobuf unmarshal failure is wrapped in serialization.NewDeserializationError together with the queue type/name. This means the stored bytes are not a valid Queue proto message.","triggerScenarios":"getQueueMetadata or getMessageCountAndLastID loads a metadata row whose MetadataPayload bytes fail qm.Unmarshal — truncated, corrupt, or not a Queue proto.","commonSituations":"Corrupted or truncated blob in the database; payload written by an incompatible proto schema version; manual DB manipulation; storage-layer bit rot.","solutions":["Inspect the metadata row for the named queue; compare its payload against a freshly created queue's payload.","Rewrite the metadata payload with a correctly marshaled persistencespb.Queue, or delete and recreate the queue.","Check for schema/version skew between the code writing the payload and the code reading it; upgrade to matching versions.","Restore the affected rows from a database backup if corruption is widespread."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"qm, err := store.GetQueueMetadata(ctx, req)\nif err != nil {\n    var deserErr *serialization.DeserializationError\n    if errors.As(err, &deserErr) {\n        // metadata blob corrupt; recreate queue or restore from backup\n    }\n    return err\n}","preventionTips":["Restore corrupted rows from DB backups rather than editing blobs by hand.","Match writer/reader Temporal versions so proto schemas are compatible.","Alert on deserialization errors in persistence metrics as corruption signals."],"tags":["serialization","protobuf","queue","data-corruption"],"backgroundTag":"protobuf-deserialization-failed","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}