Skip to content

Comments

opentelemetry-instrumentation-aws-lambda: fix improper handling of header casing#4216

Open
herin049 wants to merge 4 commits intoopen-telemetry:mainfrom
herin049:fix/aws-lambda-header-casing
Open

opentelemetry-instrumentation-aws-lambda: fix improper handling of header casing#4216
herin049 wants to merge 4 commits intoopen-telemetry:mainfrom
herin049:fix/aws-lambda-header-casing

Conversation

@herin049
Copy link
Contributor

Description

Fixes issue where request headers are extracted in a case-sensitive manner, resulting in issues with context propagation for API Gateway requests.

Fixes #4106

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

tox run -e $(tox --listenvs | grep opentelemetry-aws-lambda | tr '\n' ',')

Does This PR Require a Core Repo Change?

  • Yes. - Link to PR:
  • No.

Checklist:

See contributing.md for styleguide, changelog guidelines, and more.

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added

@herin049 herin049 requested a review from a team as a code owner February 19, 2026 03:41

if lambda_event.get("headers"):
if "User-Agent" in lambda_event["headers"]:
headers = {k.casefold(): v for k, v in lambda_event["headers"].items()}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't we have any helper to normalize headers in util-http?

Copy link
Contributor

@xrmx xrmx Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have only calls to lower(), we have an helper to normalize them as attributes, e.g.

def normalise_request_header_name(header: str) -> str:
   key = header.lower().replace("-", "_")
   return f"http.request.header.{key}"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, we can add a CIDict to util-http, but I figured that this is a simple enough fix. Looking through some of the other instrumentation libraries (e.g. Kafka if I recall right), these header casing bugs might be scattered elsewhere. Let me know what you think, I can either add another method to util-http or add a CIDict implementation.

if not isinstance(headers, dict):
headers = {}
return get_global_textmap().extract(headers)
return get_global_textmap().extract(
Copy link
Contributor

@xrmx xrmx Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I did this in another code base I've only done the header normalization for v1 using this to decide if that was the case:

def should_normalize(event):
    request_context = event.get("requestContext", {})
    return ("elb" in request_context or "requestId" in request_context) and "http" not in request_context

Maybe here it would be impractical since we are picking more stuff from the headers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'd want to normalize regardless, no? For example, even if you're using API GW v2, it's possible that a caller still might not provide headers as lowercase.


if lambda_event.get("headers"):
if "User-Agent" in lambda_event["headers"]:
headers = {k.casefold(): v for k, v in lambda_event["headers"].items()}
Copy link
Contributor

@xrmx xrmx Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have only calls to lower(), we have an helper to normalize them as attributes, e.g.

def normalise_request_header_name(header: str) -> str:
   key = header.lower().replace("-", "_")
   return f"http.request.header.{key}"

@herin049 herin049 requested review from emdneto and xrmx February 21, 2026 03:59
@herin049
Copy link
Contributor Author

I've opted to add a CIDict to opentelemetry-instrumentation, since this will likely have uses elsewhere and is not limited to just HTTP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

W3CBaggagePropagator fails to extract baggage when header name is title-cased (e.g., "Baggage" vs "baggage")

3 participants