作者注:gemini-3-pro-image-preview を呼び出す際に「Base64 decoding failed 400」エラーが発生していませんか?本記事では、エラーメッセージの分析から始まり、よくある6つの原因、Python/JavaScript/curlでの正しい実装例、そして5ステップのトラブルシューティング手順を解説します。
gemini-3-pro-image-preview インターフェースの呼び出し時に、以下の400エラーが発生したことはありませんか?
{
"status_code": 400,
"error": {
"message": "Invalid value at 'contents[0].parts[0].inline_data.data' (TYPE_BYTES), Base64 decoding failed for \"/9j/4AAQSkZJ...\" (request id: 2026050117522815159336234238114)",
"type": "shell_api_error",
"code": 400
}
}
これはAPIサービス側の問題ではありません。 リクエストボディ内の inline_data.data フィールドに含まれるBase64データが、Geminiのバックエンドで正しくデコードできていないことを示しています。エラーメッセージ内の /9j/4AAQSkZJ はJPEGファイルの標準的なBase64ヘッダー(バイナリの FF D8 FF E0 に対応)であり、データの開始部分は正常であることを示していますが、文字列全体の中にデコードを妨げる何らかの問題が含まれています。
核心的な価値: 本記事では、このエラーの6つの一般的な原因を徹底的に分析し、Python、JavaScript、curlの3つの呼び出し方法に対応した正しいサンプルコードを提供します。また、問題を迅速に特定するための5ステップの診断手順も紹介します。APIYI (apiyi.com) を経由して gemini-3-pro-image-preview を利用している場合でも、本記事の解決策はすべて適用可能です。

一、Base64 decoding failed エラーの深い理解
トラブルシューティングを始める前に、エラーメッセージの各フィールドの意味を理解しておくと、無駄な時間を大幅に削減できます。
1.1 エラーメッセージのフィールド解説
| フィールド | 意味 | 確認ポイント |
|---|---|---|
status_code: 400 |
HTTP 400 クライアントエラー | リクエスト形式の問題。サーバー故障ではない |
contents[0].parts[0] |
1番目のcontentの1番目のpartでエラー | 最初の画像partを確認 |
inline_data.data |
インラインデータのdataフィールド | 純粋なBase64文字列である必要がある |
(TYPE_BYTES) |
フィールド型がバイト配列 | Geminiバックエンドはデコード後にbytesを期待 |
Base64 decoding failed for "/9j/..." |
デコード失敗、開始は /9j/ |
開始バイトは正常、中間か末尾に問題あり |
request id: 2026050... |
リクエストID | 技術サポートへの問い合わせ時に提示 |
1.2 /9j/4AAQSkZJ で始まるのに失敗する理由
/9j/4AAQSkZJ はJPEGファイルのBase64エンコードの標準的な開始文字列です(バイナリの FF D8 FF E0 00 10 4A 46 49 46、つまりJPEG SOI + APP0 + "JFIF" 識別子に対応)。これは以下を意味します。
- ✅ データは確かにJPEG画像である
- ✅ 開始バイトは完全に正常である
- ❌ しかし、文字列全体のどこかで不正な文字や構造上の問題が発生している
この特徴から「データが全くの別物」という可能性は排除され、データの途中部分、末尾のパディング、または文字列の転送・エスケープ処理に問題がある可能性が高いと言えます。
1.3 このエラーが発生するシナリオ
gemini-3-pro-image-preview はGoogleの最新の画像生成・編集モデルであり、以下のシナリオで inline_data を渡す必要があります。
- 画像から画像生成(Image-to-Image):参照画像に基づいて新しい画像を生成
- 画像編集:元の画像に対して部分的な修正を行う
- マルチ画像合成:複数の参照画像を組み合わせて生成
- スタイル転送:参照画像をスタイルテンプレートとして使用
画像データを入力として渡す必要があるあらゆるシナリオで、Base64 decoding failed エラーが発生する可能性があります。
💡 迅速な診断のヒント:APIYI (apiyi.com) を経由して
gemini-3-pro-image-previewを呼び出している場合、コンソールで完全なリクエストログとrequest_idを確認できます。リクエストボディで実際に送信されたinline_data.dataの長さと内容を比較することで、公式APIを直接叩くよりも遥かに効率的にトラブルシューティングが行えます。
二、Base64 decoding failed エラーの6つの主な原因
発生頻度が高い順に並べています。この順番で確認することをお勧めします。
2.1 原因1:data URI プレフィックスが含まれている(最も一般的、約40%のケース)
これが圧倒的に多いエラーです。開発者がHTMLやフロントエンドのBase64文字列をそのままコピーしてしまうことが原因です。
❌ 間違った書き方:
{
"inline_data": {
"mime_type": "image/jpeg",
"data": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAA..."
}
}
✅ 正しい書き方:
{
"inline_data": {
"mime_type": "image/jpeg",
"data": "/9j/4AAQSkZJRgABAQAA..."
}
}
data:image/jpeg;base64, というプレフィックスはブラウザの <img> タグやCSSのbackgroundでのみ使用されます。Gemini APIの inline_data.data フィールドは純粋なBase64文字列のみを受け付けます。
2.2 原因2:文字列に改行や空白文字が含まれている(約25%のケース)
多くの言語のBase64エンコード関数は、76文字ごとに自動改行(PEM形式)を挿入したり、ファイル読み込み時に \n や \r が混入したりすることがあります。
❌ 問題のある例(Python):
import base64
# エラー:encodebytes() を使うと改行が挿入されます
with open("photo.jpg", "rb") as f:
data = base64.encodebytes(f.read()).decode() # \n が含まれる
✅ 正しい書き方:
import base64
# 正解:b64encode() を使用すれば改行は挿入されません
with open("photo.jpg", "rb") as f:
data = base64.b64encode(f.read()).decode("utf-8")
2.3 原因3:URLエンコードによる文字の置換(約15%のケース)
Base64の文字セットには + や / が含まれており、URL転送時に %2B や %2F に変換されることがあります。一部のHTTPクライアントが自動的にURLエンコードを行い、Gemini側でデコードに失敗する原因となります。
❌ エラーの現象:
元データ: /9j/4AAQSkZJRg+abc=
転送後: %2F9j%2F4AAQSkZJRg%2Babc%3D
✅ 解決策:
- Content-Type が
application/x-www-form-urlencodedではなくapplication/jsonであることを確認する - URLクエリパラメータではなく、JSONボディ内でBase64を転送する
- 手動で連結せず、HTTPクライアントの
json=パラメータ(Pythonのrequestsなど)を使用する
2.4 原因4:Base64文字列の切り捨て(約10%のケース)
画像サイズが大きい(数MB)場合、転送中に以下の理由でデータが切り捨てられることがあります。
- ネットワークの中断と再送
- HTTPクライアントの文字列長制限
- JSONシリアライズ時のフィールド長制限
- 中間プロキシのボディサイズ制限
調査方法:元のBase64文字列の長さを計算し、実際に送信されたリクエストボディの長さと比較してください。Base64エンコード後のサイズは元のファイルの約4/3倍になります。2MBのJPEGならエンコード後は約2.67MBです。
2.5 原因5:URL-safe Base64エンコード(約5%のケース)
Pythonの base64.urlsafe_b64encode() やNode.jsの Buffer.from(buf).toString('base64url') は、+ と / を - と _ に置き換えたURL-safe Base64を出力します。
❌ エラー:
data = base64.urlsafe_b64encode(image_bytes).decode() # - や _ が含まれる
✅ 正解:
data = base64.b64encode(image_bytes).decode("utf-8") # + や / が含まれる
Gemini APIは標準Base64(RFC 4648 §4)のみを受け付け、URL-safe Base64(RFC 4648 §5)は受け付けません。
2.6 原因6:パディングの不足または過剰(約5%のケース)
Base64文字列の長さは4の倍数である必要があり、末尾は = で埋められます。一部のライブラリの「厳格モード」では末尾の = が削除され、Gemini側でデコードエラーが発生します。
❌ エラー:
/9j/4AAQSkZJRgABAQAAAQABAAD ← 長さ27、4の倍数ではない
✅ 正解:
/9j/4AAQSkZJRgABAQAAAQABAAD= ← 末尾に = を補完、長さ28
標準の base64.b64encode() 関数を使用していれば、パディングは自動的に正しく処理されるため、手動で追加する必要はありません。
三、Base64 decoding failed エラーを解決する5ステップ

以下の順序で項目をチェックしてください。ほとんどのBase64 decoding failedエラーは、最初の3ステップで特定できます。
3.1 ステップ1:data URI プレフィックスの確認
チェック内容:
# Python 示例
if data.startswith("data:"):
print("⚠️ data URI プレフィックスが含まれています。削除が必要です")
data = data.split(",", 1)[1] # data:image/...;base64, を削除
合格条件:data フィールドが /9j/(JPEG)、iVBORw0KGgo(PNG)、R0lGOD(GIF)、UklGR(WebP)などの画像フォーマットヘッダーで始まり、data: プレフィックスが含まれていないこと。
3.2 ステップ2:改行と空白文字の削除
チェック内容:
# すべての空白文字を削除
import re
data = re.sub(r"\s+", "", data)
合格条件:文字列に \n、\r、\t、またはスペースが含まれていないこと。
3.3 ステップ3:Base64の妥当性検証
リクエストを送信する前に、ローカルで一度デコードを試みます。ローカルでデコードできない場合は、データ自体に問題があります。
import base64
try:
decoded = base64.b64decode(data, validate=True)
print(f"✅ デコード成功、元のバイト数:{len(decoded)}")
except Exception as e:
print(f"❌ デコード失敗:{e}")
ローカルで成功してもAPIでエラーが出る場合は、ステップ4に進んでください。
3.4 ステップ4:mime_type の正確性検証
mime_type は実際の画像フォーマットと一致している必要があります。一般的な有効値:
| 実際のフォーマット | 正しい mime_type | Base64 ヘッダーの特徴 |
|---|---|---|
| JPEG | image/jpeg |
/9j/4AAQSkZJ |
| PNG | image/png |
iVBORw0KGgo |
| WebP | image/webp |
UklGR |
| GIF | image/gif |
R0lGOD |
| HEIC | image/heic |
AAAAFGZ0eXBoZWlj |
mime_type: image/png と指定しているのにデータがJPEG(/9j/ で始まる)の場合、Geminiはエラーを返します。
3.5 ステップ5:画像サイズ制限の確認
Gemini APIには1回のリクエストサイズ制限があります:
- inline_data の合計サイズ ≤ 20MB(エンコード前)
- 1枚あたりの画像 推奨 ≤ 7MB(エンコード前)
- 超巨大な画像 File APIでアップロードしてから参照すること
画像が大きすぎる場合は、圧縮やリサイズを行ってから送信してください。
🎯 診断のコツ:APIYI (apiyi.com) を経由して gemini-3-pro-image-preview を呼び出している場合、コンソールで request_id を使用して完全なリクエストボディとレスポンスログを確認できます。公式APIに直接接続するよりも問題の特定が容易です。中継ログには、リクエストボディの実際のサイズや切り捨てられた位置が表示されます。
四、gemini-3-pro-image-preview 各言語での正しい呼び出し例
以下に、動作確認済みの最もシンプルで正しい実装例を記載します。そのままコピーしてご利用いただけます。
4.1 Python の完全な例(requests ライブラリを推奨)
import base64
import requests
# 1. 画像を読み込んでエンコード
def encode_image(image_path):
with open(image_path, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
# 2. リクエストの構築
api_key = "sk-your-apiyi-key" # 実際の APIキー に置き換えてください
base_url = "https://vip.apiyi.com/gemini" # APIYI API中継サービスのアドレス
model = "gemini-3-pro-image-preview"
image_b64 = encode_image("input.jpg")
payload = {
"contents": [{
"parts": [
{
"inline_data": {
"mime_type": "image/jpeg", # 実際の画像形式と一致させる必要があります
"data": image_b64 # プレフィックスなしの純粋な Base64
}
},
{
"text": "この画像をゴッホの星月夜風に変換して"
}
]
}]
}
# 3. リクエストの送信
response = requests.post(
f"{base_url}/v1beta/models/{model}:generateContent",
headers={
"x-goog-api-key": api_key,
"Content-Type": "application/json" # 重要:JSON 形式
},
json=payload # 重要:data= ではなく json= を使用
)
print(response.json())
4.2 JavaScript / Node.js の完全な例
const fs = require('fs');
const fetch = require('node-fetch');
async function callGemini() {
// 1. 画像を読み込んでエンコード(標準 Base64 を使用、base64url は不可)
const imageBuffer = fs.readFileSync('input.jpg');
const imageB64 = imageBuffer.toString('base64'); // ✅ 'base64url' は使用しないでください
// 2. リクエストの構築
const apiKey = 'sk-your-apiyi-key';
const baseUrl = 'https://vip.apiyi.com/gemini'; // APIYI API中継サービス
const model = 'gemini-3-pro-image-preview';
const payload = {
contents: [{
parts: [
{
inline_data: {
mime_type: 'image/jpeg',
data: imageB64 // 純粋な Base64
}
},
{ text: 'この画像をゴッホの星月夜風に変換して' }
]
}]
};
// 3. リクエストの送信
const response = await fetch(
`${baseUrl}/v1beta/models/${model}:generateContent`,
{
method: 'POST',
headers: {
'x-goog-api-key': apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
}
);
console.log(await response.json());
}
callGemini();
4.3 curl コマンドラインの例
# 1. 画像をエンコードしてファイルに保存(コマンドラインの長さ制限を回避)
base64 -i input.jpg -o input.b64
# または macOS の場合:base64 -w 0 input.jpg > input.b64
# 2. JSON ペイロードの作成
cat > payload.json <<EOF
{
"contents": [{
"parts": [
{
"inline_data": {
"mime_type": "image/jpeg",
"data": "$(cat input.b64)"
}
},
{ "text": "この画像をゴッホの星月夜風に変換して" }
]
}]
}
EOF
# 3. リクエストの送信
curl -X POST \
"https://vip.apiyi.com/gemini/v1beta/models/gemini-3-pro-image-preview:generateContent" \
-H "x-goog-api-key: sk-your-apiyi-key" \
-H "Content-Type: application/json" \
-d @payload.json
⚠️ curl に関する注意点:macOS で
curl -d "$(base64 input.jpg)"を実行すると、デフォルトで改行コードが挿入される場合があります。必ずbase64 -w 0(Linux)やbase64 -i ... | tr -d '\n'(macOS)を使用して改行を除去してください。
五、誤ったリクエスト vs 正しいリクエスト:完全比較

| チェック項目 | 誤った例 | 正しい例 |
|---|---|---|
| data フィールドの先頭 | data:image/jpeg;base64,/9j/... |
/9j/4AAQSkZJ... |
| 改行処理 | 76文字ごとに \n が含まれる |
1行の連続した文字列 |
| 文字セット | - _ を含む(URLセーフ) |
+ / を含む(標準) |
| 末尾のパディング | = なし、または余分な = |
自動的に正しいパディング |
| mime_type | 実際の形式と不一致 | 実際の形式と厳密に一致 |
| HTTP ヘッダー | application/x-www-form-urlencoded |
application/json |
| 転送方式 | URL クエリパラメータ | JSON ボディフィールド |
| 画像サイズ | 1画像あたり > 20MB | 1画像あたり ≤ 7MB |
六、APIYI 调用 gemini-3-pro-image-preview 的优势
如果排查后仍无法定位问题,使用 APIYI (apiyi.com) 中转 gemini-3-pro-image-preview 具有以下显著优势:
| 优势 | 说明 |
|---|---|
| 完整的请求日志 | 控制台可查看 request_id 对应的完整请求/响应内容 |
| 错误快速反查 | 通过 request_id 一键定位失败原因 |
| 原生格式兼容 | 无需修改代码,仅需替换 base_url 即可 |
| 不限并发 | 批量图像编辑场景不会被限流 |
| 充值优惠 | 充值 100 美金送 10%(约等于官网 85 折) |
| 国内人民币充值 | 支持微信/支付宝直接支付 |
接入 APIYI 调用 gemini-3-pro-image-preview 只需修改两个变量:
# 官方接口
base_url = "https://generativelanguage.googleapis.com"
# 改为 APIYI 中转(其余代码完全不变)
base_url = "https://vip.apiyi.com/gemini"
七、Base64 decoding failed 常见问题 FAQ
Q1: 为什么本地 base64.b64decode() 能解码成功,调用 API 还是报错?
最可能的原因是传输环节出现了问题。常见情况包括:
- HTTP 客户端将
+编码成了%2B(应使用application/json而不是 form-urlencoded) - JSON 序列化时字符串被截断(请检查 body 大小限制)
- 中间代理或网关设置了 body size 限制(如 Nginx 的
client_max_body_size)
如果您怀疑是网络环节的问题,可以使用 APIYI (apiyi.com) 中转,控制台日志会显示请求体到达中转服务器时的实际内容,便于定位。
Q2: gemini-3-pro-image-preview 支持哪些图像格式?
支持的 mime_type 包括:
image/jpeg(推荐,文件最小)image/png(适用于含透明通道的场景)image/webp(兼顾质量和体积)image/gif(仅取第一帧)image/heic/image/heif(iPhone 拍摄格式)
不支持 BMP、TIFF、SVG 等格式,需要先进行转换。
Q3: 一个 request 能传几张图?
gemini-3-pro-image-preview 单次请求最多支持:
- inline_data parts:3-5 张(取决于图像总大小)
- 总数据量:≤ 20MB(编码前所有 inline_data 之和)
- 建议组合:如需 5 张以上图像参考,请使用 File API 上传后通过
file_data引用
Q4: 报 Base64 decoding failed 但其他模型(如 gemini-2.5-flash)正常?
这种情况通常是因为 gemini-3-pro-image-preview 对图像格式的校验更为严格。新模型的输入校验标准更高:
- 旧模型可能容忍部分前缀或换行
- 新模型严格按照 RFC 4648 §4 进行校验
- 建议按照本文 4.1 节的最简正确示例重写,并逐项验证
Q5: 用 APIYI (apiyi.com) 调用时,使用什么 base_url?
APIYI 调用 gemini-3-pro-image-preview 的标准 base_url 是:
https://vip.apiyi.com/gemini
完整的端点路径为:
https://vip.apiyi.com/gemini/v1beta/models/gemini-3-pro-image-preview:generateContent
API Key 通过请求头 x-goog-api-key 传递,与 Google 官方完全一致。
Q6: request_id 的作用是什么?
request_id(如 2026050117522815159336234238114)是本次请求的唯一标识,其作用如下:
- 联系技术支持时提供,可快速定位问题
- 复现问题时引用,技术团队可以查到完整请求日志
- 统计错误模式,多个 request_id 出现相同错误说明存在系统性问题
如果您使用 APIYI (apiyi.com) 中转,可以在控制台直接搜索 request_id 查看详情,无需额外联系客服。
Q7: 图像太大该如何压缩?
推荐使用 Pillow 在客户端预先压缩:
from PIL import Image
import io
import base64
def compress_image(path, max_size_kb=2048):
img = Image.open(path)
# 缩放最长边到 1568(Gemini 推荐)
img.thumbnail((1568, 1568))
buffer = io.BytesIO()
img.save(buffer, format="JPEG", quality=85, optimize=True)
return base64.b64encode(buffer.getvalue()).decode("utf-8")
压缩后通常能在保持视觉质量的同时大幅降低体积,避免触发 20MB 限制。
Q8: 错误信息显示 (TYPE_BYTES) 是什么意思?
TYPE_BYTES 是 Google Protocol Buffers 的字段类型标识,表示该字段在 Gemini 后端期望接收的是 解码后的字节数组(bytes)。当 Base64 解码失败时,无法得到 bytes,因此会报此错误。这是底层 protobuf 校验的提示,并非配置问题。
八、Key Takeaways 核心要点
- ✅ エラーの本質:
inline_data.dataフィールドの Base64 文字列が Gemini バックエンドでデコードできないこと - ✅ よくある6つの原因(頻度順):data URI プレフィックス / 改行コード / URL エンコード / 切り詰め(Truncation) / URL-safe 文字 / パディングエラー
- ✅ 5ステップのトラブルシューティング:プレフィックス削除 → 空白削除 → ローカル検証 → mime_type 確認 → サイズ確認
- ✅ Python 推奨:
base64.b64encode()+ requests のjson=パラメータを使用 - ✅ JavaScript 推奨:
Buffer.toString('base64')を使用('base64url' ではない) - ✅ curl 推奨:Base64 を一度ファイルに書き出し、
-d @file.jsonで参照する - ✅ APIYI の強み:ネイティブ形式の完全互換、コンソールでの request_id によるログ追跡、同時実行数無制限
- ✅ サポートへの連絡:request_id を控えておくと、迅速な特定が可能
九、まとめ
gemini-3-pro-image-preview で Base64 decoding failed エラーが発生する場合、99% はクライアント側のリクエスト構築の問題であり、サーバー側の障害ではありません。エラーメッセージに含まれる /9j/4AAQSkZJ は、開始バイトが正当な JPEG Base64 であることを示しており、問題はデータの中間処理(プレフィックスの混入、改行コード、URL エンコード、URL-safe 文字、またはデータの切り詰め)にあることがわかります。
本記事第3章の5ステップのトラブルシューティング手順に従えば、ほとんどの問題は5分以内に特定できます。複雑なシナリオ(圧縮後もサイズが大きい、複数画像の組み合わせ、特殊なエンコードなど)については、第4章の3言語の完全なサンプルコードを参考にしてください。そのままコピー&ペーストで実行可能です。
マルチモーダルプロジェクトのために安定した gemini-3-pro-image-preview の接続先をお探しなら、APIYI (apiyi.com) が提供する Gemini シリーズの API 中継サービスをご検討ください。ネイティブ形式と100%の互換性があり(base_url を置き換えるだけ)、同時実行数は無制限(バッチ画像編集に最適)、100ドルのチャージで10%ボーナス付与(公式サイト比で実質15%オフ)、日本円での決済対応(海外クレジットカード不要)、そしてコンソールから request_id を使って完全なログを追跡できるため、トラブルシューティングのコストを大幅に削減できます。
🎯 次のアクション:まずは本記事第3章の5ステップのトラブルシューティングを順番に実行してください。それでも解決しない場合は、request_id を控えた上で APIYI (apiyi.com) のテクニカルサポートまでお問い合わせください。その際、リクエストボディ(機密情報は伏せてください)を添付いただければ、通常1時間以内に正確な原因を特定いたします。
参考資料
-
Google Gemini API 公式ドキュメント:画像理解と生成
- リンク:
ai.google.dev/gemini-api/docs/image-generation - 説明: inline_data / file_data フィールドの仕様、mime_type リスト
- リンク:
-
Gemini 3 開発者ガイド:新モデル移行ガイド
- リンク:
ai.google.dev/gemini-api/docs/gemini-3 - 説明: gemini-3-pro-image-preview と旧モデルの差異
- リンク:
-
RFC 4648 – The Base16, Base32, and Base64 Data Encodings:Base64 標準仕様
- リンク:
datatracker.ietf.org/doc/html/rfc4648 - 説明: §4 標準 Base64 と §5 URL-safe Base64 の違い
- リンク:
-
APIYI 公式サイト:Gemini / Claude / OpenAI 全シリーズ API中継サービス
- リンク:
apiyi.com - 説明: ネイティブ形式互換、同時接続数無制限、人民元決済対応、100ドルチャージで10%ボーナス付与
- リンク:
著者: 技術チーム
最終更新: 2026-05-02
APIYI について: APIYI (apiyi.com) は、プロフェッショナルな AI 大規模言語モデル API 中継サービスプロバイダーです。gemini-3-pro-image-preview、Claude Sonnet 4.5、Claude Opus 4.7、GPT シリーズなど、全シリーズのモデルを安定して提供しています。Gemini/OpenAI/Anthropic の各ネイティブ形式と完全に互換性があり、コンソールでは request_id を使用した詳細なリクエストログの照会が可能です。100ドルのチャージで10%のボーナス(公式サイト比で約15%オフ相当)が付与され、同時接続数は無制限、迅速な技術サポートを提供しています。
