2026年5月以降、Maven Centralが新しいレート制限を導入し、依存をダウンロードするビルドがHTTP 429(Too Many Requests)で失敗する事象が報告されています。MavenやGradle、Leiningenを使うJava・Kotlin・Scala・ClojureのプロジェクトをCircleCIで運用している場合、依存取得のステップで突然ビルドが落ちる、あるいは取得が遅くなるといった影響を受けます。
CircleCIはこの問題に対して2系統の対策を提供しています。本記事では、そのうち広く利用できる「レジストリキャッシュ・プロキシ(registry cache and proxy)」を、実際にCircleCI上で動かして確認した手順で紹介します。
本記事で使用するcircleci experiment registry configはexperimental(実験的)コマンドです。インターフェースは今後変更される可能性があります。本記事の内容は2026年6月時点のものです。
Maven Central の 429 と CircleCI の2系統の対策
今回の事象の発生源は、CircleCIではなくMaven Central側のレート制限です。Maven Centralが一定時間あたりのリクエスト数に制限をかけたため、CIのように短時間で多数の依存を取得する環境が429を受けやすくなりました。レート制限の詳細はSonatype側の一次情報を参照してください。
これに対してCircleCIが用意している対策は2つあります。1つ目はIP Ranges機能の利用者向けの対策で、CircleCIがSonatypeと連携し、CircleCIの専用IPレンジをMaven Centralのアクセス許可リストに追加しています。このためIP Ranges機能を使っているジョブは、レート制限の影響を受けにくくなっています。2つ目が本記事で扱うレジストリキャッシュ・プロキシで、CircleCIが運用するプロキシ経由でMaven Centralから依存を取得することで、Maven Centralへの直接リクエストを減らし、レート制限を回避します。こちらはIP Rangesを使っていない環境でも利用できます。
どちらに該当するかの判断は、次の表を目安にしてください。
| 状況 | 推奨される対策 |
|---|---|
| IP Ranges 機能を利用している | 追加対応は不要な場合が多い(allowlist 済み) |
| IP Ranges を利用していない | 本記事のレジストリキャッシュ・プロキシ |
| Maven / Gradle / Leiningen で依存取得している | 本記事のプロキシが適用対象 |
前提条件
本記事の手順は、以下を前提としています。
- CircleCIのDocker executor上でMaven、Gradle、またはLeiningenを使って依存を取得するジョブであること
- Java環境のイメージ(例:
cimg/openjdk)を使用していること
特別なツールのインストールは不要です。cimg/openjdkイメージにはMavenが含まれており、後述のcircleci experiment registry configコマンドもジョブ実行環境内でそのまま利用できます。これは実際にcimg/openjdkのジョブ内でコマンドが動作することを確認しています。
circleci experiment registry configコマンドで設定する
このコマンドは、Maven Centralへの依存取得をCircleCIのプロキシ経由に切り替える設定を、ジョブ実行時に書き込みます。具体的には、Mavenの設定ファイル~/.m2/settings.xmlにMaven Centralをミラーするプロキシ設定を書き込みます。あわせて認証用の環境変数CIRCLECI_MAVEN_REGISTRY_ENDPOINTとCIRCLECI_REGISTRY_TOKENを$BASH_ENVにエクスポートします。
対応するビルドツールはフラグで切り替えます。
| フラグ | 対象 | 書き込み先 |
|---|---|---|
--maven |
Maven | ~/.m2/settings.xml |
--gradle |
Gradle | Gradle の設定 |
--lein |
Leiningen | Leiningen の設定 |
--all |
上記すべて | 各設定ファイル |
--env |
設定ファイルを書かず、環境変数のみエクスポート | (ファイル書き込みなし) |
次のconfig.ymlは、Mavenプロジェクトで依存を取得する最小のジョブに、このコマンドを組み込んだ例です。ポイントは、circleci experiment registry config --mavenを依存取得のステップより前に置くことです。プロキシ設定が書き込まれる前に依存を取得すると、Maven Centralへ直接アクセスしてしまうためです。
version: 2.1
jobs:
build:
docker:
- image: cimg/openjdk:21.0
steps:
- checkout
- run:
name: Maven Central プロキシを設定 # 依存取得より前に実行する
command: circleci experiment registry config --maven
- run:
name: 依存を取得
command: mvn -B dependency:go-offline
workflows:
build:
jobs:
- build
上記の例では、circleci experiment registry config --mavenのステップで~/.m2/settings.xmlが書き込まれ、続くmvnのステップがその設定を読み込んでプロキシ経由で依存を取得します。Gradleを使っている場合は--mavenを--gradleに置き換え、依存取得コマンドをGradleのもの(例: gradle dependencies)に変更してください。
実際にジョブで実行すると、コマンドは認証情報をsettings.xmlに書き込み、有効期限付きのトークンを発行したことをログに出力します。
ログのvalid untilが示すとおり、書き込まれるトークンには有効期限があり、ジョブごとに発行される短命のものです。
プロキシ経由になったことを確認する
設定が書き込まれただけでは、依存取得が実際にプロキシ経由になったとは限りません。ここでは、書き込まれた設定の中身、エクスポートされた環境変数、そして依存の取得元が切り替わったことを順に確認します。
書き込まれたsettings.xmlを確認する
circleci experiment registry config --mavenの実行後に~/.m2/settings.xmlを表示すると、Maven Central(central)をミラーするプロキシ設定が書き込まれていることを確認できます。次は実際に書き込まれた内容から、認証情報を伏せたものです。
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0">
<servers>
<server>
<id>circleci-registry</id>
<username>aws</username>
<password>REDACTED(トークンが書き込まれる。ログ・スクショでは必ずマスクする)</password>
</server>
</servers>
<profiles>
<profile>
<id>circleci-registry</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>circleci-registry</id>
<url>https://circleci-<account>.d.codeartifact.<region>.amazonaws.com/maven/maven-proxy/</url>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>circleci-registry</activeProfile>
</activeProfiles>
<mirrors>
<mirror>
<id>circleci-registry</id>
<name>circleci-registry</name>
<url>https://circleci-<account>.d.codeartifact.<region>.amazonaws.com/maven/maven-proxy/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
</settings>
<mirrors>の<mirrorOf>central</mirrorOf>により、本来Maven Central(central)へ向かうリクエストが、<url>で指定されたプロキシのエンドポイントへ振り向けられます。あわせて<profiles>と<activeProfiles>も書き込まれ、同じプロキシエンドポイントをリポジトリとして有効化します。このエンドポイントのホスト名から分かるとおり、CircleCIのレジストリキャッシュ・プロキシの実体はAWS CodeArtifactのリポジトリです。<username>はawsで固定され、<password>にはコマンドが発行した認証トークンが書き込まれます。エンドポイントのアカウントやリージョンの値はCircleCI側で自動的に生成されるため、手動で設定する必要はありません。
settings.xmlの<password>には有効な認証トークンが書き込まれます。このトークンは短命でジョブごとに発行されますが、ログやスクリーンショットを共有・公開する際は必ずマスクしてください。
エクスポートされた環境変数を確認する
コマンドはsettings.xmlの書き込みと同時に、CIRCLECI_MAVEN_REGISTRY_ENDPOINTとCIRCLECI_REGISTRY_TOKENを$BASH_ENVにエクスポートします。$BASH_ENVに書き出されるため、これらの値は後続のステップでも参照できます。別のステップでエンドポイントとトークンの有無を確認すると、値が引き継がれていることが分かります。
ENDPOINTにはCodeArtifactのプロキシエンドポイントが入り、TOKENは値を出力せず設定済みであることだけを確認しています。トークンそのものはログに出さないよう、-nで存在確認のみを行っています。
依存の取得元が切り替わったことを確認する
最も分かりやすい確認方法は、mvnの出力にあるDownloading fromの行を見ることです。プロキシを設定する前と後で、取得元のホストが変わります。
設定前は、Maven Central(central)から直接ダウンロードしています。
circleci experiment registry config --mavenを実行した後は、取得元がcircleci-registry、すなわちCodeArtifactのプロキシエンドポイントに切り替わります。
取得元がcentral(repo.maven.apache.org)からcircleci-registry(CodeArtifactのエンドポイント)へ変わっていれば、依存取得がプロキシ経由になっています。このDownloading fromの差が、プロキシが効いていることの直接の証拠です。
注意事項
導入と運用にあたっての注意点を整理します。
- このコマンドはexperimentalです。将来インターフェースが変わる可能性があるため、
config.ymlに組み込む際は、CircleCIの更新情報を継続的に確認してください。CircleCIは今後、対応レジストリの拡充とこの設定の自動化を予定しています。 - IP Ranges機能をすでに利用している場合は、Maven Centralのアクセス許可リストに追加済みのため、本記事のプロキシ設定を追加しなくてもレート制限の影響を受けにくくなっています。両方を必ず併用する必要はありません。自分の環境がどちらに該当するかを確認した上で、必要な対策を選んでください。
- トークンを含む認証情報が
settings.xmlやログに出力されます。記事化やチーム共有で画面を見せる場合は、必ずマスクしてください。
まとめ
Maven Centralの429に対しては、circleci experiment registry config --mavenを依存取得ステップの前に1行追加することで、依存取得をCircleCIのプロキシ(実体はAWS CodeArtifact)経由に切り替えられます。IP Ranges機能を使っていない環境でも適用でき、設定変更のコストは小さく済みます。
本記事ではMavenを例に紹介しましたが、--gradleや--lein、複数をまとめて設定する--allも同じ仕組みで利用できます。設定ファイルを書かずに環境変数だけを使いたい場合は--envを指定してください。
詳細は以下を参照してください。
- 機能の更新情報: New: Registry cache and proxy for Maven Central
- 背景とレート制限の告知: CircleCI Discuss のアナウンス
- IP Ranges機能: IP ranges のドキュメント




