e-Gov法令API v2のエラーコードと制限:404・400の実測一覧、Base64、巨大法令のサイズ
e-Gov法令API v2で存在しないID・不正なasof・不正なパラメータを実際に叩き、ステータスコードとエラー本文を一覧化。Base64と文字コード、Accept と response_format の優先順位、民法・会社法・所得税法の取得サイズと所要時間を2026年9月14日のcurl実測で記録しました。
e-Gov法令API v2のエラーは、API本体が返す code と message のJSON、フレームワークが返す timestamp 付きJSON、サーバー手前が返すHTMLの3系統に分かれます。 どの形で返ってきたかを見れば、パラメータの値が悪いのか、リクエストの組み立てが壊れているのかを一段目で切り分けられます。
この記事は、存在しないID・不正な日付・不正なパラメータを2026年9月14日に実際に叩いて、ステータスコードと本文を記録したものです。あわせてBase64と文字コード、Accept と response_format の優先順位、民法・会社法・所得税法の取得サイズと所要時間も実測しました。エンドポイントごとの正常系は逆引きリファレンスを参照してください。
- API本体のエラーは
codeで判定する。 400004(日付)、400044(asof の下限)、404001(0件)、404004(本文なし)が実務で当たりやすい4つです。 - 0件の表現がエンドポイントで違う。
lawsは200の空配列、keywordとlaw_revisionsは404です。 asofは2017-04-01以降のみ。 それより前はデータ整備の対象外で、400になります。- 巨大法令はgzipで受ける。 所得税法の全文JSONは16.4MBですが、
--compressedなら662KBで届きます。
エラーの3系統を見分ける
同じ400でも本文の形が違います。実際に返ってきた3つを並べます。
# 1. API本体(application/json): パラメータの値が不正{"code":"400004","message":"日付(asof等)が誤っています。"}
# 2. フレームワーク既定(application/json): 必須パラメータ欠落・未知パス{"timestamp":"2026-09-14T04:29:20.884+00:00","status":400,"error":"Bad Request","path":"/api/2/keyword"}
# 3. サーバー手前(text/html): URLに角括弧をそのまま含めた<!doctype html><html lang="en"><head><title>HTTP Status 400 – Bad Request</title>...1はOpenAPI定義の error_info スキーマどおりで、code の先頭3桁がHTTPステータスに対応します。2は keyword を付けずに /keyword を呼んだときと、存在しないパス /api/2/nope(404)で返りました。3は elm=LawTitle[1] のように角括弧をエンコードせずに送ったときで、レスポンスヘッダは Server: CloudFront、X-Cache: Error from cloudfront でした。3が出たらパラメータの値ではなくURLの組み立てを疑います。
なお POST /laws は405で本文が Method Not Allowed の18バイト、Accept: text/html は406で Not Acceptable でした。
実測したエラー一覧
| リクエスト | ステータス | code | message |
|---|---|---|---|
law_data/999AC9999999999 | 404 | 404004 | 指定のパラメータで取得できる法令本文ファイルは存在しません。 |
law_data/322AC0000000049_19000101_000000000000000(存在しない履歴ID) | 404 | 404004 | 同上 |
law_file/xml/999AC9999999999 | 404 | 404004 | 同上 |
attachment/999AC9999999999_19000101_000000000000000 | 404 | 404004 | 同上 |
law_revisions/999AC9999999999 | 404 | 404001 | 取得結果が0件です。 |
keyword?keyword=生成AI(0件) | 404 | 404001 | 取得結果が0件です。 |
laws?law_title=民法&limit=0 | 200 | — | total_count 0、laws は空配列 |
law_data/...?asof=2025-13-45 | 400 | 400004 | 日付(asof等)が誤っています。 |
law_data/...?asof=20250601(ハイフンなし) | 400 | 400004 | 同上 |
law_data/...?asof=1900-01-01 | 400 | 400044 | 法令の時点(asof)には2017-04-01以降を指定してください。 |
law_data/...?asof=2099-01-01 | 200 | — | 未施行の版 ..._20281223_...(UnEnforced)が返る |
laws?law_type=Foo | 400 | 400001 | 法令種別(law_type、law_num_type)が誤っています。 |
laws?limit=abc | 400 | 400007 | 取得件数(limit)が数字ではありません。 |
laws?limit=-1 | 400 | 400027 | 取得件数(limit)が負値(異常値)です。 |
keyword?keyword=電子計算機&limit=1001 | 400 | 400005 | 取得件数(limit)は1件以上1000件以内を指定してください。 |
keyword?keyword=(空) | 400 | 400019 | 検索ワード(keyword)が未設定又は誤っています。 |
law_data/...?elm=Foo_1 / elm=MainProvision-Article_9999 | 400 | 400021 | 要素(elm)に合致する要素が法令本文に存在しません。 |
law_data/...?json_format=medium | 400 | 400045 | JSONレスポンスの形式(json_format)が誤っています。 |
laws?response_format=yaml | 400 | 400040 | レスポンス形式(response_format)が誤っています。 |
law_file/pdf/322AC0000000049 | 400 | 400042 | ファイル種別(file_type)が誤っています。 |
law_revisions/...?law_title=%2F^労働基準法$%2F(スラッシュをエンコード) | 400 | 400033 | 法令名又は法令略称(law_title)が誤っています。 |
未知のパラメータ(foo=bar)は無視されて200でした。タイプミスしたパラメータ名はエラーにならず、絞り込みが効かないまま結果が返るので、件数が想定より多いときはパラメータ名を確認してください。
asof の下限2017-04-01は、ヘルプにある「平成29年4月1日時点以降の法令データ整備を実施」という記述と一致します。それ以前の条文はこのAPIでは取れません。
0件の返り方はエンドポイントで違う
law_data の404004は「本文ファイルが無い」の意味で、存在しない法令IDでも、存在するIDに存在しない履歴IDを付けたときでも同じコードでした。law_revisions の404001は「一覧が0件」です。エージェントに渡すときは、この2つのコードを「止まるべきエラー」ではなく「検索条件を見直す合図」として扱うよう指示しておくと、無理に別の法令で埋める挙動を防げます。
Accept と response_format の優先順位
response_format を付けない場合は Accept ヘッダで形式が決まり、判断できなければJSONです。組み合わせを変えて laws?law_id=322AC0000000049&limit=1 を呼びました。
Accept なし -> 200 application/jsonAccept: application/json -> 200 application/jsonAccept: application/xml -> 200 application/xml <laws_response>...Accept: application/xml + response_format=json -> 200 application/json(response_format が優先)Accept: text/html -> 406 "Not Acceptable"Accept: application/xml + law_type=Foo -> 400 application/xml <ErrorInfo><code>400001</code>...エラー本文も形式に追従し、XMLでは <ErrorInfo> 要素で返ります。JSONの Content-Type は application/json だけで charset の指定がありません。中身はUTF-8で、XML(law_file/xml)は <?xml version="1.0" encoding="UTF-8" standalone="no"?> の宣言付きでした。Shift_JISで返ることはなかったので、受け側はUTF-8固定で問題ありません。
Base64 になる条件と確認方法
law_data は外側の response_format(既定 json)と本文の law_full_text_format を別々に指定でき、2つが食い違うときだけ law_full_text がBase64になります。 労働基準法で確認しました。
curl -s "https://laws.e-gov.go.jp/api/2/law_data/322AC0000000049?law_full_text_format=xml" \ | python -c "import json,sys,base64; t=json.load(sys.stdin)['law_full_text']; print(len(t), t[:24]); print(base64.b64decode(t)[:60])"531044 PExhdyBFcmE9IlNob3dhIiBMb'<Law Era="Showa" Lang="ja" LawType="Act" Num="049" PromulgateDay="07"'law_full_text が PExhdy... で始まっていたらBase64です(<Law をBase64にした先頭がこの並びになります)。復号すると398,281バイトのXMLで、同じ法令を response_format=xml で取ったときの本文とサイズが一致しました。復号の実装はPython実装の記事に、XMLをMCP用JSONに変換する設計はXML→JSONの記事にあります。
Base64を避けたいだけなら、JSONが欲しいときは law_full_text_format を付けない、XMLが欲しいときは response_format=xml にする、の二択で済みます。
巨大法令のサイズと所要時間
大きな法令をどの形式で取ると何バイトになるか、5本で測りました。json_full は law_data の既定、json_light は json_format=light、xml は response_format=xml、b64 はJSON応答に law_full_text_format=xml を付けたもの、file_xml は law_file/xml、gz は json_full を curl --compressed で受けたときの転送量です。
| 法令 | json_full | json_light | xml | b64 | file_xml | gz | 所要時間(json_full) |
|---|---|---|---|---|---|---|---|
| 日本国憲法 | 81,725 | 70,505 | 77,463 | 102,494 | 76,207 | 11,636 | 0.16秒 |
| 労働基準法 | 419,817 | 339,023 | 399,678 | 532,090 | 398,337 | 45,477 | 0.25秒 |
| 民法 | 1,618,344 | 1,413,309 | 1,634,260 | 2,178,218 | 1,632,975 | 162,391 | 0.30秒 |
| 会社法 | 3,034,237 | 2,716,464 | 3,173,168 | 4,230,076 | 3,171,829 | 272,794 | 0.94秒 |
| 所得税法 | 16,404,145 | 9,705,006 | 16,443,288 | 21,923,565 | 16,441,924 | 662,111 | 1.61秒 |
読み取れることを3つ挙げます。
- Base64は素の1.33倍。 所得税法では16.4MBが21.9MBに膨らみます。JSONとXMLを混ぜないだけで転送量が減ります。
- gzipが最も効く。
law_dataはAccept-Encoding: gzipに応じて所得税法を662KB(4%)まで圧縮しました。law_fileは--compressedを付けても16.4MBのままで、圧縮されません。 json_format=lightは所得税法で約4割減。 速度目的というより、構造を簡素にする目的のオプションです。
所要時間はすべて2秒以内で、curlでは所得税法(16.4MB)でも問題なく取れました。30回連続で law_data を呼んでもすべて200で、レート制限には当たりませんでしたが、公式資料に制限値の記載は見当たらず、応答ヘッダは Cache-Control: max-age=0, no-cache, no-store で毎回オリジンまで届きます。定期実行では自分で間隔を空け、本文の一括取得が目的なら公式が案内しているXML一括ダウンロードを使う方が向いています。
Windows で日本語パラメータが化ける
Windowsで検証していて、law_title=民法 が0件になる現象に当たりました。原因はcurlに渡る日本語のバイト列です。-w '%{url_effective}' で実際に送ったURLを表示すると分かります。
Git Bash(MSYS)から curl.exe -> law_title=%96%af%96%40 (Shift_JIS)→ 0件PowerShell 7.6 から curl.exe -> law_title=%E6%B0%91%E6%B3%95 (UTF-8) → 11件同じ --data-urlencode "law_title=民法" でも、呼び出す殻によってUTF-8で渡るかShift_JISで渡るかが変わりました。原因が分からない0件は、まず url_effective を見てください。回避策は、あらかじめパーセントエンコードした文字列を渡すか、URL オブジェクトにエンコードを任せられるNode.jsやPythonで呼ぶことです(TypeScript実装の記事では URL.searchParams に任せています)。
まとめ
- エラーは3系統。
codeとmessageのJSONならパラメータの値、timestamp付きなら必須パラメータやパス、HTMLならURLの組み立て(角括弧など)を疑う - 0件は
lawsが200の空配列、keywordとlaw_revisionsが404(404001)。law_dataの存在しないIDは404004 asofは2017-04-01以降のみ(400044)。未来日付は未施行の版が返るresponse_formatはAcceptより優先。text/htmlは406。JSONとXMLを混ぜたときだけBase64- 所得税法の全文JSONは16.4MB、gzipなら662KB。
law_fileは圧縮されない。30連続でもレート制限には当たらなかった
エラーを「失敗」で一括りにせず、コードごとに「条件を見直す」「IDを確定し直す」「URLを直す」と対応を分けておくと、エージェントに任せたときにも黙って別の法令で埋める挙動を防げます。その線引きは法令をAIで扱うときの安全境界の考え方と同じです。
この記事の情報・検証メモ
- egov
- japanese-law
- legal-tech
- api
- troubleshooting
- json
- windows
- 公開日
- 情報確認
- 参考リンク
- 3件
- 更新性
- 定期更新
仕様・料金・提供範囲が変わりやすいテーマは、公開日・更新日・情報確認日を分けて管理します。 導入前には必ず記事末尾の一次情報と公式ドキュメントで最新状況を確認してください。