RedisのDUMP/RESTOREで発生する「ERR DUMP payload version or checksum are wrong」の解決方法

intermediate🔴 Redis2026-06-17| Redis (全バージョン)。主にメジャーバージョンの異なるインスタンス間での移行や、手動でのデータ転送時に発生します。

Error Message

ERR DUMP payload version or checksum are wrong
#redis#dump#restore#移行#シリアル化#バージョン

エラーメッセージ

DUMPRESTORE を使用した Redis インスタンス間のキーの移行は通常シンプルですが、次のような壁に突き当たることがあります。

(error) ERR DUMP payload version or checksum are wrong

原因について

おそらく、2つの一般的な問題のいずれかに直面しています。Redis のバージョンに互換性がないか、転送中にバイナリデータが破損したかのどちらかです。

  • 前方互換性の問題: Redis は古いデータの読み取り(後方互換性)には優れていますが、未来を予測することはできません。Redis 7.0(RDB バージョン 10 を使用)からキーをダンプし、それを Redis 6.2(RDB バージョン 9)で復元しようとすると失敗します。古いサーバーは新しいフォーマットを理解できないためです。
  • バイナリの破損: DUMP コマンドは生のバイナリデータを出力します。これをターミナルからコピー&ペーストしたり、標準の UTF-8 テキストファイルとして保存したりすると、ヌルバイトが失われたり特殊文字が破損したりすることがあります。たとえ 1 ビットの変化であっても、チェックサムは無効になります。

解決方法

1. Redis のバージョンを確認する

まず、ソースサーバーと送信先サーバーの両方のバージョンを確認することから始めましょう。両方のインスタンスで以下を実行します。

redis-cli INFO Server | grep redis_version

ソースのメジャーバージョンが送信先よりも高い場合、RESTORE は確実に失敗します。例えば、Redis 7.2 から 6.0 への DUMP ペイロードによるデータ移動は不可能です。

2. MIGRATE コマンドを使用する

サーバー同士がネットワーク経由で直接通信できる場合は、DUMPRESTORE を手動で使うのはやめましょう。MIGRATE コマンドはアトミック(不可分)であり、転送を内部で処理するため、エンコーディングによるトラブルを完全に回避できます。

# 構文: MIGRATE host port key destination-db timeout [COPY] [REPLACE]

user:profile:100 というキーを 10.0.0.5 のサーバーに移動するには、次のように入力します。

MIGRATE 10.0.0.5 6379 "user:profile:100" 0 2000 COPY

2000 は 2 秒のタイムアウト設定です。COPY フラグを指定すると、ソース側にキーを保持したまま移行できるため、安全な移行に不可欠です。

3. コード内でバイナリデータを適切に扱う

スクリプトを書く際は、ペイロードを文字列としてではなく、必ずバイト配列として扱ってください。Python の場合は、意図しないエンコーディング変換を避けるためにバイトモードを使用していることを確認してください。

import redis

# 自動デコードを無効にして接続
src = redis.Redis(host='source-db', decode_responses=False)
dst = redis.Redis(host='dest-db', decode_responses=False)

key_name = "session:active:99"
raw_payload = src.dump(key_name)

if raw_payload:
    try:
        # 0 は有効期限なしを意味します。既存のキーを上書きするには replace=True を使用します
        dst.restore(key_name, 0, raw_payload, replace=True)
        print("転送に成功しました")
    except redis.exceptions.ResponseError as e:
        print(f"移行に失敗しました: {e}")

4. 古いバージョンへデータを移動する場合

ダウングレードが必要な場合(例:クラウドプロバイダーの Redis 7 からオンプレミスの Redis 6 への移動など)、DUMP は機能しません。主に 2 つの選択肢があります。

  • 論理移行: HGETALL(ハッシュ用)や LRANGE(リスト用)など、データ型に応じたコマンドを使用してデータを取得するスクリプトを作成します。その後、HSETRPUSH を使用して送信先へ再挿入します。時間はかかりますが、バージョンに依存しません。
  • 送信先のアップグレード: 最も安定した修正方法は、送信先の Redis をソースのバージョンと一致させるか、それ以上にアップグレードすることです。これにより、すべての互換性の問題が回避されます。

検証方法

問題を切り分けるために、単純な文字列でテストしてください。基本的な文字列でも失敗する場合は、ほぼ確実にバージョンの不一致が原因です。

# ソース側
SET debug_key "test"
DUMP debug_key
# 出力例: "\x00\x04test\n\x00\xbd\xc6\x1e\x96\x9c\x13\xf6\xec"

# 送信先側
RESTORE debug_key 0 "\x00\x04test\n\x00\xbd\xc6\x1e\x96\x9c\x13\xf6\xec"
# OK が返されるはずです

プロのヒントと予防策

クリップボードを信用してはいけません。ターミナルからバイナリデータをコピーすると、隠し文字が追加されたりヌルバイトが削除されたりすることがよくあります。ファイルを使用する必要がある場合は、redis-cli --raw DUMP key > key.bin を使用して、ターミナルのロケール設定によって出力が変更されないようにしてください。

私はインポート前に必ず移行ファイルを検証します。ToolCraft の ハッシュジェネレーター を使用して、エクスポートしたデータの SHA-256 チェックサムを作成できます。転送前後のハッシュを比較することで、scprsync の過程で 1 バイトも失われていないことを確認できます。

Related Error Notes