kopia/kopia · error

unable to marshal log entry bytes

Error message

unable to marshal log entry bytes

What it means

Wraps a failure from json.Marshal of the compactionLogEntry struct in registerCompaction (index_blob_manager_v0.go:189). The compaction log entry (input/output blob metadata) must be serialized to JSON before being encrypted and stored; marshaling fails only if the payload cannot be encoded (e.g. unsupported value types such as NaN-like or invalid data in the metadata). This is effectively an internal invariant violation — the struct is plain JSON-serializable data.

Solutions

  1. Inspect the wrapped marshal error for which value could not be encoded.
  2. Verify blob.Metadata values passed as inputs/outputs are well-formed (no invalid fields).
  3. Upgrade the library if the error persists with plain metadata; report as a bug since compactionLogEntry is expected to always marshal.
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: verify compaction metadata is JSON-encodable before registering
if _, err := json.Marshal(&compactionLogEntry{InputMetadata: inputs, OutputMetadata: outputs}); err != nil {
	return errors.Wrap(err, "compaction metadata not serializable")
}

Type guard

func validMetadata(in, out []blob.Metadata) bool {
	for _, m := range append(append([]blob.Metadata{}, in...), out...) {
		if m.BlobID == "" { return false }
	}
	return true
}

Try / catch

if err := m.registerCompaction(ctx, inputs, outputs, settleTime); err != nil {
	if strings.Contains(err.Error(), "unable to marshal log entry bytes") {
		// invariant violation: inspect blob.Metadata contents / report bug
	}
	return err
}

Prevention

When it happens

Trigger: json.Marshal(&compactionLogEntry{...}) returns an error while registerCompaction runs — practically only when InputMetadata/OutputMetadata contain values json cannot encode.

Common situations: Very rare; would indicate corrupted or unexpected blob.Metadata contents, a Go stdlib marshal failure, or memory exhaustion during very large compactions.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07). Data as JSON: /api/errors/02532259d9147f4b. Report an issue: GitHub.

Appendix: source

Thrown at repo/content/indexblob/index_blob_manager_v0.go:189

		return nil, errors.Wrap(err, "error cleaning up index blobs")
	}

	if compacted {
		return &maintenancestats.CompactIndexesStats{
			DroppedContentsDeletedBefore: opt.DropDeletedBefore,
		}, nil
	}

	return nil, nil
}

func (m *ManagerV0) registerCompaction(ctx context.Context, inputs, outputs []blob.Metadata, maxEventualConsistencySettleTime time.Duration) error {
	logEntryBytes, err := json.Marshal(&compactionLogEntry{
		InputMetadata:  inputs,
		OutputMetadata: outputs,
	})
	if err != nil {
		return errors.Wrap(err, "unable to marshal log entry bytes")
	}

	compactionLogBlobMetadata, err := m.enc.EncryptAndWriteBlob(ctx, gather.FromSlice(logEntryBytes), V0CompactionLogBlobPrefix, "")
	if err != nil {
		return errors.Wrap(err, "unable to write compaction log")
	}

	contentlog.Log4(ctx, m.log,
		"registered compaction",
		blobparam.BlobMetadataList("inputs", inputs),
		blobparam.BlobMetadataList("outputs", outputs),
		blobparam.BlobID("compactionLogBlobID", compactionLogBlobMetadata.BlobID),
		logparam.Time("compactionLogBlobTimestamp", compactionLogBlobMetadata.Timestamp))

	if err := m.deleteOldBlobs(ctx, compactionLogBlobMetadata, maxEventualConsistencySettleTime); err != nil {
		return errors.Wrap(err, "error deleting old index blobs")
	}

View on GitHub (pinned to 82495e54b5)