Claude Media
「archive integrity check」の対処 — Claude Codeのプラグイン改ざん検知エラー

「archive integrity check」の対処 — Claude Codeのプラグイン改ざん検知エラー

「Plugin archive integrity check failed」でzip配布のプラグインが入らないときの原因3パターンと対処。sha256の再計算手順、256MiB上限などarchiveソースの仕様もまとめます。

Plugin archive integrity check failed for <url>: expected sha256 <A>, got <B> — zip配布のプラグインを入れようとしてこう出たら、照合に失敗しています。エントリに登録されたsha256と、実際にダウンロードしたファイルのダイジェストが違うということです。Claude Codeはインストールを拒否し、プラグインキャッシュには何も反映しません。原因は3通りに絞れます。

「archive integrity check」の意味

Claude Codeのプラグインマーケットプレイスは、archiveソースでzipファイルをHTTPSで配布できます。archiveエントリにsha256を添えておくと、ダウンロードしたファイルのダイジェストを登録値と照合し、一致しなければその場でインストールを止めます。壊れたファイルや差し替えられたファイルを、気づかないまま使ってしまう事態を防ぐ仕組みです。

sha256は任意項目です。付けなければ照合は発生しません。付ける場合は64文字の16進数で、大文字小文字どちらでも書けます。エラー全文の末尾には「The archive was not installed.」に続けて、エントリのsha256とURLの配信内容を確かめる旨の一文が付きます。マーケットプレイス全体の仕組みはClaude Codeプラグイン完全ガイドにあります。

原因は3パターンに絞れる

エラーメッセージは「一致しない」としか言いません。原因は次の3つのどれかです。

原因

ダイジェスト不一致の3つの原因

  • ピン計算後にファイルが変わった

    公開者がダイジェストを計算した後で、URL先のzipが更新されました。バージョン番号だけ据え置いて中身を差し替えた場合が典型です。

  • ダイジェストの入力ミス

    marketplace.jsonに書いたsha256の値そのものが違っています。別のビルドの値を貼った場合などです。

  • URLが別ファイルを返している

    意図と違うファイルが配信されています。

3つとも、インストールする側では直せません。修正はマーケットプレイスの公開者の作業です。

インストールしている側の切り分け

手順

公開者に連絡する前に試すこと

  1. 1

    カタログを最新化する

    公開者がエントリをすでに直しているかもしれません。

    claude plugin marketplace update <marketplace-name>

    claude plugin marketplace update --helpでは、名前を省くと設定済みの全マーケットプレイスが対象になると表示されます。

  2. 2

    もう一度インストールする

    同じ不一致が出るなら、カタログ側がまだ直っていません。

  3. 3

    エラーの2つの値を見比べる

    expectedがmarketplace.jsonの登録値、gotが実際にダウンロードしたファイルの値です。エラーに出るURLを自分でcurl -Oで落とし、shasum -a 256の結果がgotと一致するなら、いま配信されているファイルは確かに登録値と別物です。

  4. 4

    公開者にどのファイルをピンしたか尋ねる

    2つの値と、エラー先頭に出たURLを添えて伝えると、原因が絞れます。

プラグインを公開している側の直し方

手順

ダイジェストを正しく更新する手順

  1. 1

    配信中のファイルを手元に取る

    CDNのキャッシュが古いzipを返していないか確かめるため、手元のビルド成果物ではなく、実際に配信されるURLからダウンロードします。

  2. 2

    ダイジェストを計算する

    shasum -a 256 my-plugin.zip

    Windows PowerShellではGet-FileHashを使います。

    Get-FileHash -Algorithm SHA256 my-plugin.zip
  3. 3

    marketplace.jsonの値を上書きする

    出力された値でsha256を書き換えます。

  4. 4

    validateで書式を確かめる

    マーケットプレイスのディレクトリでclaude plugin validate .を実行します。

validateが見るのは書式まで

v2.1.287で、sha256にabcと書いたエントリを検証すると、次のエラーで失敗します。

✘ Found 1 error:
 
  ❯ plugins.1.source.sha256: Must be a 64-character hex SHA-256 digest
 
✘ Validation failed

64桁の16進数にそろえて検証し直すと通ります。検証はmarketplace.jsonの中身だけを読むので、値がzipの実物と合っているかまでは判定できません。実物との一致は、インストール時の照合だけが見ています。

headersHelperを使うarchiveエントリでsha256を省いた場合は、警告が出ます。

⚠ Found 2 warnings:
 
  ❯ plugins[0].source.sha256: Plugin "formatter" fetches its archive with a headersHelper but sets no sha256 pin. Consider pinning the digest so the bytes users install are exactly the ones you reviewed (omit it only if you rely on digest-versioned updates).

警告の括弧書きにある「digest-versioned updates」は、次の節の話です。

更新が利用者に届く条件はversionの有無で変わる

sha256を差し替えただけで利用者に更新が届くかは、versionを書いているかで決まります。

くらべる

versionを書く場合と省く場合

文字列で更新を制御

version を明示する

マニフェストかマーケットプレイスのエントリにversionがあれば、それが優先されます。zipとダイジェストを差し替えても、versionの文字列を上げない限り、利用者はキャッシュ済みの古いコピーのままです。

ダイジェストで更新を判定

version を省く

archiveソースでは、sha256ピンの先頭12文字がバージョンとして使われます。ピンが無ければ、ダウンロードしたファイルのダイジェストが使われます。ダイジェストを更新すれば新しいバージョンとして扱われます。

plugin.jsonとmarketplace.jsonの両方にversionを書くと、インストール時はplugin.jsonの値が採用されます。相対パスのエントリではclaude plugin validateも警告します。片方だけにそろえてください。

エントリの書き方は次のとおりです。sha256はソースの中に置きます。

{
  "name": "formatter",
  "source": {
    "source": "archive",
    "url": "https://artifacts.example.com/formatter-2.0.0.zip",
    "sha256": "6bfa50e3d2e00c052b46abe51fff89346ac803e45771f76dcf6df1ab74cca5e1"
  }
}

zipを差し替えたのに利用者側でclaude plugin updateが<name> is already at the latest version (<version>).と返す場合は、Claude Codeが計算したバージョンが前回と同じです。versionを明示していて文字列を上げていないか、sha256の更新漏れがないかを疑います。このバージョンはプラグインのキャッシュディレクトリの名前にも使われます。上のエントリの例なら、versionを省いたときのバージョンは6bfa50e3d2e0です。ダイジェストを更新するたびに、キャッシュの置き場所も新しい名前になります。

archiveソースのダウンロード条件

照合の前に、ダウンロード自体が条件を満たす必要があります。

項目内容
対応バージョン内容Claude Code v2.1.224以降
URL内容https://必須。ループバック・リンクローカル・クラウドメタデータのホストは拒否
ダウンロード上限内容256MiB、サーバーの応答待ちは120秒
リダイレクト内容最大5回。各リダイレクト先もhttps://で、同じホスト制限を受ける
展開後の上限内容10万エントリ、1ファイル512MiB、合計1GiB、圧縮率50倍まで
フォルダ構造内容プラグインのルートはzipの最上位か、1階層下

サイズ超過や応答の遅れで落ちた場合は、ダイジェストの比較まで進んでいないので、integrity check failedは出ません。zipの展開後の上限を超えたときも、インストールが失敗する段階が違います。上限はエントリ数、1ファイル、合計サイズ、圧縮率の4種類です。zipを作り直す前に、どれに当たったかを中身のサイズから確かめます。

urlソースで追加するマーケットプレイスのmarketplace.jsonにも別の上限があり、5MiBまで、サーバーの応答待ちは10秒です。カタログ自体が取れないときは、プラグインのzipとは別の問題です。

v2.1.224より前のClaude Codeはarchiveソースに対応していません。zipのダウンロードや照合の前に止まるので、ダイジェスト不一致とは別の原因です。この場合はClaude Codeを更新します。

マーケットプレイスの名前が原因で止まる別のエラーもあります。公式用に予約された名前を使った追加は拒否されます。名前の扱いは「Marketplace is registered from an untrusted source」の対処で扱っています。

非対話の環境でheadersHelper付きのarchiveを入れる

headersHelperでトークンを発行するエントリは、インストール時にそのコマンドと配布URLが画面に表示され、承認してはじめてzipをダウンロードします。CIのように標準入出力が端末でない環境では、承認の入力ができません。claude plugin install --helpでは、この場合に-yが必須と説明されています。-yはv2.1.229以降で使え、-yも--accept-commandもないままだとインストールは拒否され、終了コードは1です。

claude plugin install my-plugin@your-marketplace --yes

--accept-command <sha256>(v2.1.271以降)は、--jsonで実行した結果のshownCommand.sha256を渡して、表示されたコマンドだけを承認するオプションです。ここでいうsha256はコマンド文字列のダイジェストで、marketplace.jsonのarchiveのピンとは別物です。コマンドかURLが承認後に変わると、インストールも更新も拒否されます。

複数のプラグインをまとめて入れる場合は、コマンド付きのプラグインだけが拒否されます。ほかのプラグインは入ります。バックグラウンドの自動更新で拒否されたときは、/pluginのErrorsタブに表示されるので、そこから単独でインストールまたは更新します。

認証付きの配布URLではヘッダーの届く範囲に注意する

社内の限定公開サーバーからzipを配布する場合、headersでHTTPヘッダーを付けて認証します。置き場所は2つあります。

  • マーケットプレイスのurlソース: extraKnownMarketplacesに登録したURL。同じスキーム・ホスト・ポートのarchiveダウンロードにだけヘッダーが付く
  • プラグインのエントリ: v2.1.238以降、sourceの横に書ける。そのエントリのダウンロードにだけ付く

同じ名前のヘッダーが両方にあると、エントリの値が送られます。リダイレクトでオリジンを離れた時点で、どちらのヘッダーも落ちます。マーケットプレイス本体と別ドメインのCDNにzipを置く構成では、認証ヘッダーは届かない前提の構成になります。エントリ側にheadersを書けば、その配布物には付きます。

headersHelperのコマンドが0以外で終了した場合、10秒を超えた場合、JSONオブジェクト以外を出力した場合は、そのダウンロード自体が行われません。この失敗もダイジェスト不一致とは別の症状です。コマンドは標準出力にヘッダー名と文字列値のJSONオブジェクトを1つ出して終了する必要があります。

urlソースのマーケットプレイスでheadersHelperを使うと、1回の実行結果が最大60秒再利用されます。プラグインのエントリにheadersHelperを書くには"strict": falseが要り、ないとclaude plugin validateがエラーにします。

認証の失敗は、ダイジェスト不一致とは別の段階で起きます。照合に進むのはダウンロードが完了した後なので、expected sha256とgotが並んだ文面が出ているなら、ダウンロード自体は成功しています。

よくある質問

ダイジェストを消せばインストールできますか

公開者側でsha256フィールドごと削除すれば照合が行われず、インストールは通ります。ただし改ざん検知を外す対応になるため、真正性を保証したい配布物には向きません。暫定の回避策です。

GitHubやnpm経由のプラグインでも同じエラーが出ますか

出ません。このエラーはarchiveソース専用です。github・url・git-subdirソースのバージョンはコミットSHAの先頭12文字から決まり、npmソースはversionが無いとunknownになります。

まとめ

このエラーは、公開者側のピンと配信ファイルのずれが原因で、インストールする側にできるのはカタログの更新と公開者への報告までです。再配布のあとで利用者に更新が届くかどうかは、エントリがversionを明示しているかで決まります。明示しているなら、文字列を上げ忘れていないかが確認点になります。

この記事を共有:XはてブLinkedIn