temporalio/temporal · error
unmarshal payload for queue with type %v and name %v failed:
Error message
unmarshal payload for queue with type %v and name %v failed: %w
What it means
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.
Source
Thrown at common/persistence/sql/queue_v2.go:364
}
return q.extractQueueMetadata(metadata)
}
func (q queueV2) extractQueueMetadata(metadataRow *sqlplugin.QueueV2MetadataRow) (*persistencespb.Queue, error) {
if metadataRow.MetadataEncoding != enumspb.ENCODING_TYPE_PROTO3.String() {
return nil, fmt.Errorf(
"queue with type %v and name %v has invalid encoding: %w",
metadataRow.QueueType,
metadataRow.QueueName,
serialization.NewUnknownEncodingTypeError(metadataRow.MetadataEncoding, enumspb.ENCODING_TYPE_PROTO3),
)
}
qm := &persistencespb.Queue{}
err := qm.Unmarshal(metadataRow.MetadataPayload)
if err != nil {
return nil, serialization.NewDeserializationError(
enumspb.ENCODING_TYPE_PROTO3,
fmt.Errorf("unmarshal payload for queue with type %v and name %v failed: %w",
metadataRow.QueueType,
metadataRow.QueueName,
err),
)
}
return qm, nil
}
func (q *queueV2) getMaxMessageID(ctx context.Context, queueType persistence.QueueV2Type, queueName string, tc sqlplugin.TableCRUD) (int64, bool, error) {
lastMessageID, err := tc.GetLastEnqueuedMessageIDForUpdateV2(ctx, sqlplugin.QueueV2Filter{
QueueType: queueType,
QueueName: queueName,
Partition: defaultPartition,
})
switch {
case err == nil:
return lastMessageID, true, nil
case errors.Is(err, sql.ErrNoRows):View on GitHub (pinned to bde624efd1)
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.
Defensive patterns
Strategy: try-catch
Try / catch
qm, err := store.GetQueueMetadata(ctx, req)
if err != nil {
var deserErr *serialization.DeserializationError
if errors.As(err, &deserErr) {
// metadata blob corrupt; recreate queue or restore from backup
}
return err
} Prevention
- 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.
When it happens
Trigger: getQueueMetadata or getMessageCountAndLastID loads a metadata row whose MetadataPayload bytes fail qm.Unmarshal — truncated, corrupt, or not a Queue proto.
Common situations: Corrupted or truncated blob in the database; payload written by an incompatible proto schema version; manual DB manipulation; storage-layer bit rot.
Related errors
- queue with type %v and name %v has invalid encoding: %w
- %w: payload marshal error: %w
- serializer error
- corrupted history event batch, eventID is not contiguous
- history task from queue has nil blob
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/9eee96d0f7fcb25b.
Report an issue: GitHub.