AWS API Gateway返回{"message":"not found"}问题排查求助
问题排查:AWS API Gateway调用返回{"message":"Not Found"}
通过Terraform部署HTTP类型的AWS API Gateway(后续将添加HTTPS),部署成功后调用Invoke URL时,无论是否包含路径段,多数场景返回{"message":"Not Found"},怀疑路由配置问题,附上相关信息请求排查。
相关Terraform代码
#create API Gateway HTTP API resource "aws_apigatewayv2_api" "est_api" { name = "est-api" protocol_type = "HTTP" } resource "aws_apigatewayv2_integration" "lambda_integration" { api_id = aws_apigatewayv2_api.est_api.id integration_type = "AWS_PROXY" integration_uri = aws_lambda_function.est_server.invoke_arn } resource "aws_apigatewayv2_route" "lambda_root" { api_id = aws_apigatewayv2_api.est_api.id route_key = "ANY /" target = "integrations/${aws_apigatewayv2_integration.lambda_integration.id}" } #give permission to api gateway to write logs resource "aws_iam_role" "est_gw_role" { name = "est-gw-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [{ Effect = "Allow" Principal = { Service = "apigateway.amazonaws.com" } Action = "sts:AssumeRole" }] }) } resource "aws_iam_role_policy_attachment" "est_gw" { role = aws_iam_role.est_gw_role.name policy_arn = aws_iam_policy.est_gw_policy.arn } resource "aws_apigatewayv2_stage" "est_gw_stage" { api_id = aws_apigatewayv2_api.est_api.id name = "prod" auto_deploy = true access_log_settings { destination_arn = aws_cloudwatch_log_group.est_gw_logs.arn format = jsonencode({ requestId = "$context.requestId", ip = "$context.identity.sourceIp", httpMethod = "$context.httpMethod", routeKey = "$context.routeKey", status = "$context.status", protocol = "$context.protocol", responseLength = "$context.responseLength" }) } } resource "aws_lambda_permission" "apigw_lambda" { statement_id = "AllowAPIGatewayInvoke" action = "lambda:InvokeFunction" function_name = aws_lambda_function.est_server.function_name principal = "apigateway.amazonaws.com" source_arn = "${aws_apigatewayv2_api.est_api.execution_arn}/*" } output "est_service_url" { value = aws_apigatewayv2_stage.est_gw_stage.invoke_url }
测试结果
command ran on each = curl -X GET ...amazonaws.com With route_key API / curl on ...amazon.com/prod = {"message":"Not Found"} curl on ...amazon.com/prod/ = {"ERROR": "'http'"} curl on ...amazon.com/ = {"message":"Not Found"} curl on ...amazon.com = {"message":"Not Found"} With route_key $default curl on ...amazon.com/prod = {"ERROR": "'http'"} curl on ...amazon.com/prod/ = {"ERROR": "'http'"} curl on ...amazon.com/ = {"message":"Not Found"} curl on ...amazon.com = {"message":"Not Found"} with route_key API /{proxy+} curl on ...amazon.com/prod = {"message":"Not Found"} curl on ...amazon.com/prod/ = {"ERROR": "'http'"} curl on ...amazon.com/ = {"message":"Not Found"} curl on ...amazon.com = {"message":"Not Found"}
CloudWatch日志情况
仅返回{"ERROR": "'http'"}时API Gateway有日志,Lambda仅在以下情况触发: With route_key API / /prod/ /prod With route_key $default /prod/ With route_key API /{proxy+} /prod/
Lambda期望不同输入,但至少应返回合适错误信息。
排查关键点
- 路由匹配逻辑问题:HTTP API的Invoke URL包含阶段前缀
/prod,当前路由ANY /仅匹配{invoke_url}/prod/(带末尾斜杠)的请求,{invoke_url}/prod(不带斜杠)或直接访问根路径{invoke_url}/时无匹配路由,返回404。 - Lambda权限范围:当前
source_arn配置为${aws_apigatewayv2_api.est_api.execution_arn}/*,可调整为${aws_apigatewayv2_api.est_api.execution_arn}/prod/*或${aws_apigatewayv2_api.est_api.execution_arn}/*/*,确保覆盖阶段+路径的所有请求。 - 路由配置优化:若需匹配所有路径,建议使用
$default路由(无需指定路径前缀),或配置ANY /{proxy+}捕获所有子路径,同时注意阶段前缀的匹配规则。 - Lambda事件解析:返回
{"ERROR": "'http'"}时Lambda已触发,说明该请求匹配路由,错误由Lambda内部逻辑导致,需检查Lambda是否正确解析HTTP API的代理事件结构(HTTP API与REST API的事件格式存在差异)。
内容的提问来源于stack exchange,提问作者veila
相关产品推荐
相关产品推荐

