Unable to execute HTTP request (DynamoDB, Java SDK)

TL;DR — Java SDK 從未收到 HTTP 回應:到 DynamoDB 端點的 TCP 連線失敗。對 localhost:8000 而言,這表示 DynamoDB Local 未執行(或在另一個連接埠上)— 而在 Docker/SAM 容器內部,localhost 是_容器_,而非你的機器,因此模擬器在該位址上無法連到。啟動模擬器、修正端點,並從容器使用主機可連到的位址。

這是什麼意思

com.amazonaws.SdkClientException: Unable to execute HTTP request:
Connect to localhost:8000 [localhost/127.0.0.1] failed: Connection refused

SdkClientException(v1:AmazonClientException)是 SDK 的用戶端失敗包裝 — 請求在 DynamoDB 看到它之前就死了。巢狀的原因告訴你哪個網路步驟失敗了:Connection refused(沒有東西在監聽)、connect timed out(沒有路由/防火牆),或 UnknownHostException(主機名稱無法解析,通常是區域或端點拼錯)。這是 botocore Could not connect to the endpoint URL 的 Java 對應版本。

為什麼會發生

  • DynamoDB Local 未執行 — 它從未啟動、在啟動時崩潰(原生程式庫連接埠衝突),或隨你上一個終端機結束。
  • 連接埠或協定錯誤 — Local 預設為明碼 http 上的 8000https://localhost:8000 或錯誤連接埠的端點會被拒絕。
  • 容器內的 localhost — 在 Docker/SAM(sam local invoke)中執行的程式碼撥號到它_自己_的 loopback。主機上(或兄弟容器中)的模擬器不在那裡。
  • 對真正的 AWS:沒有網路路徑 — 企業代理未在 SDK 的 HTTP 用戶端上設定、VPC 沒有到 DynamoDB 的路由/端點,或拼錯的區域產生不存在的主機名稱。

如何修正

  1. 確認你撥號之處有東西在監聽:

    curl http://localhost:8000    # DynamoDB Local answers 400 with an AmazonDynamoDBv2 body

    若失敗,啟動模擬器(java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jardocker run -p 8000:8000 amazon/dynamodb-local)。

  2. 將用戶端指向正確的端點(v2 SDK):

    DynamoDbClient client = DynamoDbClient.builder()
        .endpointOverride(URI.create("http://localhost:8000"))
        .region(Region.US_EAST_1)
        .build();
  3. 從容器中,不要撥號 localhost — 使用 host.docker.internal:8000(Docker Desktop)、compose 服務名稱(http://dynamodb:8000),或將兩個容器接到同一個 Docker 網路。對 sam local,傳入與模擬器容器共用的 --docker-network

  4. 對真正的 AWS,驗證區域主機名稱正確,並在你的網路需要時設定 SDK 的代理設定;從私有子網路,新增 DynamoDB gateway VPC 端點或 NAT 路由。

一旦端點回應,端到端驗證資料流動 — DynoTable 桌面應用程式同時連到 DynamoDB Local 與真正的 AWS,讓你看到你的 Java 程式碼命中(或未命中)的表格。要建立請求本身嗎?DynamoDB Expression Builder 會產生正確的 key condition 與帶型別的值。

相關錯誤

References

最後驗證於 2026-07-13,對照上方連結的 AWS 官方文件。

不必透過主控台就能操作 DynamoDB

DynoTable 是一款快速的 DynamoDB 桌面用戶端 — 瀏覽表格、執行 SQL 風格的查詢,並在本機編輯項目。