Helmエラー解決:rendered manifests contain a resource that already existsの対処法

intermediate☸️ Kubernetes2026-05-24| Kubernetesクラスター, Helm v3.x, Linux/macOS/Windows CLI

Error Message

Error: UPGRADE FAILED: rendered manifests contain a resource that already exists. Unable to continue with update: existing resource conflict
#kubernetes#helm#devops#トラブルシューティング#k8s

Helmで行き詰まったとき

ルーチンの更新を本番環境にプッシュし、CI/CDパイプラインからグリーンのチェックマーク(成功)を期待しているとします。しかし、デプロイが突然停止します。Helmが特定の、イライラさせるようなエラーを返します:rendered manifests contain a resource that already exists。リリースがスタックし、クラスターは中途半端な状態になります。

Error: UPGRADE FAILED: rendered manifests contain a resource that already exists. Unable to continue with update: existing resource conflict

この競合は、HelmがConfigMap、Secret、Serviceなどのリソースを作成しようとした際に、そのリソースが既に名前空間に存在するものの、現在のHelmリリースの管理下にない場合に発生します。通常、これは誰かが kubectl を使用して手動でクラスターを調整したか、以前のインストール試行が失敗して「孤立した」リソースが残されたことが原因です。

なぜHelmは処理を拒否するのか

Helmは過保護な設計になっています。helm upgrade を実行すると、YAMLマニフェストが生成され、稼働中のクラスターと比較されます。同じ名前と種類(Kind)のリソースが見つかり、それに現在のリリースの特定のメタデータ(ラベルとアノテーション)が含まれていない場合、Helmは処理を中止します。Helmはそのリソースが他の誰かの管理下にあると判断し、予期せぬデータ損失を防ぐために上書きを拒否します。

通常、以下の3つのシナリオで見られます:

  • チームメンバーがクイックフィックスのために手動で kubectl apply を実行した。
  • 以前の helm install が5分でタイムアウトし、クラッシュした。
  • レガシーなモノリシックチャートから新しいサブチャートにリソースを移動している。

ステップ1:原因を特定する

エラーメッセージは通常、問題を引き起こしている特定のリソースを特定します。以下のように表示されるはずです:

Existing resource conflict: kind: Secret, namespace: production, name: app-credentials

そのリソースの現在の状態を確認し、実際に何かに管理されているか見てみましょう:

kubectl get secret app-credentials -n production -o yaml

metadata セクションを確認してください。app.kubernetes.io/managed-by: Helmmeta.helm.sh/release-name アノテーションがない場合、Helmはそのリソースを「所有」していません。それは孤立したリソースです。

オプションA:クイックリセット(削除して再作成)

もしそのリソースがステートレス(重要なデータを保持しないServiceやConfigMapなど)であれば、最も早い解決策はそれを削除することです。次回のアップグレード試行時に、Helmがそれを再作成します。

# 競合しているリソースを削除
kubectl delete secret app-credentials -n production

# アップグレードを再試行
helm upgrade --install my-app ./charts/my-app -n production

警告: 検証済みのバックアップがない限り、PersistentVolumeClaims や、本番環境の固有のキー(RDSのパスワードなど)を含む Secrets に対してこれを行わないでください。

オプションB:リソースをHelmの管理下に取り込む

ダウンタイムが1秒も許されない場合があります。この場合、既存のリソースをHelmが所有していることを「教える」必要があります。これは、Helmが期待するラベルとアノテーションを手動で適用することで行います。

既存のリソースにタグを付けるために、以下のコマンドを実行します:

# 変数を定義
RELEASE_NAME="my-app"
NAMESPACE="production"
RESOURCE_KIND="secret"
RESOURCE_NAME="app-credentials"

# 必要なアノテーションを追加
kubectl annotate $RESOURCE_KIND $RESOURCE_NAME -n $NAMESPACE meta.helm.sh/release-name=$RELEASE_NAME
kubectl annotate $RESOURCE_KIND $RESOURCE_NAME -n $NAMESPACE meta.helm.sh/release-namespace=$NAMESPACE

# 必要なラベルを追加
kubectl label $RESOURCE_KIND $RESOURCE_NAME -n $NAMESPACE app.kubernetes.io/managed-by=Helm

タグを付けたら、再度 helm upgrade を実行してください。Helmはそのリソースを自身のものとして認識し、シームレスに更新します。

「Another Operation in Progress」エラーの修正

以前の試行が中断された場合(CIランナーが300秒後にタイムアウトしたなど)、二次的なエラー another operation is in progress が表示されることがあります。Helmはデプロイがまだ実行中であると考え、リリースの状態を pending-upgrade としてロックします。

このロックを解除するには、その特定の失敗した試行を追跡するためにHelmが使用しているSecretを見つけて削除する必要があります。これらは通常、sh.helm.release.v1.[RELEASE_NAME].v[VERSION] という名前です。

# 全てのリリースのバージョンをリストして最大の番号を確認
kubectl get secrets -n production | grep sh.helm.release.v1.my-app

# 「pending」バージョンのSecret(例:v15)を削除
kubectl delete secret sh.helm.release.v1.my-app.v15 -n production

そのSecretが削除されると、Helmは最後に成功したバージョン(例:v14)に戻り、アップグレードを再試行できるようになります。

検証と予防

修正後、リリースが正常であることを確認します:

  • helm status my-app -n production を実行し、STATUS: deployed であることを確認します。
  • メタデータを確認します:kubectl get secret app-credentials -n production -o jsonpath='{.metadata.labels}'。Helmの管理ラベルが表示されているはずです。

今後これを避けるために、パイプラインでは常に --atomic フラグを使用してください。これにより、デプロイが失敗した場合にHelmが自動的に前の安定した状態にロールバックし、リリースが pending ループでスタックするのを防ぎます。

Related Error Notes