Skip to content

into_api_gateway_v2_request joins cookies with ";" instead of "; ", violating RFC 6265 and breaking strict parsers #1142

@sbougerel

Description

@sbougerel

Describe the bug

into_api_gateway_v2_request reconstructs the Cookie header by joining the cookies array from the API Gateway v2 event payload with ";" (no space). This violates RFC 6265 §4.2.1, which mandates "; " (semicolon followed by a space) as the cookie-pair separator. The result is a non-compliant Cookie header that breaks any downstream cookie parser that follows the spec strictly like BetterAuth.

Affected code

lambda-http/src/request.rs

if let Some(cookies) = ag.cookies {
    if let Ok(header_value) = HeaderValue::from_str(&cookies.join(";")) {
        headers.insert(http::header::COOKIE, header_value);
    }
}

The join produces:

cookie1=value1;cookie2=value2

instead of the RFC-compliant:

cookie1=value1; cookie2=value2

Note: the broken behavior is also explicitly asserted in the test suite, meaning the non-compliant output is enforced as correct:

assert_eq!(cookie_header, Ok("cookie1=value1;cookie2=value2"));

This test assertion would need to be updated alongside the fix.

RFC 6265 reference

RFC 6265 §4.2.1 defines the
grammar as:

cookie-header = "Cookie:" OWS cookie-string OWS
cookie-string = cookie-pair *( ";" SP cookie-pair )

SP is a mandatory single space (%x20). The ";" separator without a following space is not a valid cookie-string per the spec.

Real-world impact

I discovered this issue while deploying a Next.js application on AWS Lambda behind API Gateway v2, using
aws-lambda-web-adapter.

The better-auth library's getSessionCookie helper parses the raw Cookie header by splitting on "; ". Because lambda_http joins cookies with ";" only, the entire cookie string is treated as a single unparseable token, causing getSessionCookie to return null even when the session cookie is present.

I have submitted a corresponding fix to better-auth to make their parser lenient (better-auth/better-auth#9465), but the root cause is in lambda_http: the header should be constructed correctly here.

Expected behavior

The Cookie header reconstructed from ag.cookies should join pairs with "; " to produce a spec-compliant value:

cookie1=value1; cookie2=value2

Environment

  • lambda_http: current HEAD (e397be4)
  • Trigger: AWS API Gateway HTTP API (v2 payload format)
  • Runtime: AWS Lambda (Node.js via aws-lambda-web-adapter, but the bug is in the Rust lambda_http crate itself)
  • Framework: Next.js 16 (App Router)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions