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

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions