encode/httpx · warning · KeyError

{key}

Error message

{key}

What it means

KeyError raised by Headers.__getitem__ when the requested header key does not exist in the (case-insensitive) header multimap. Unlike dict.get, indexing with [] is strict. httpx lowercases and encodes the key for lookup; if no matching header is present it raises KeyError(key).

Source

Thrown at httpx/_models.py:302

    def __getitem__(self, key: str) -> str:
        """
        Return a single header value.

        If there are multiple headers with the same key, then we concatenate
        them with commas. See: https://tools.ietf.org/html/rfc7230#section-3.2.2
        """
        normalized_key = key.lower().encode(self.encoding)

        items = [
            header_value.decode(self.encoding)
            for _, header_key, header_value in self._list
            if header_key == normalized_key
        ]

        if items:
            return ", ".join(items)

        raise KeyError(key)

    def __setitem__(self, key: str, value: str) -> None:
        """
        Set the header `key` to `value`, removing any duplicate entries.
        Retains insertion order.
        """
        set_key = key.encode(self._encoding or "utf-8")
        set_value = value.encode(self._encoding or "utf-8")
        lookup_key = set_key.lower()

        found_indexes = [
            idx
            for idx, (_, item_key, _) in enumerate(self._list)
            if item_key == lookup_key
        ]

        for idx in reversed(found_indexes[1:]):
            del self._list[idx]

View on GitHub (pinned to b5addb64f0)

Solutions

  1. Use .get(): response.headers.get('Content-Type') (returns None) or .get('Content-Type', default).
  2. Use `in` first: if 'Authorization' in request.headers.
  3. Use get_list() if the header may appear multiple times.
  4. Validate header presence before logic that depends on it.

Example fix

// before
ctype = response.headers['Content-Type']  # KeyError if absent
// after
ctype = response.headers.get('Content-Type', 'application/octet-stream')
Defensive patterns

Strategy: validation

Validate before calling

# Use .get() with a default instead of indexing
ctype = response.headers.get('Content-Type', 'application/octet-stream')
# Or check presence first
has_ctype = 'Content-Type' in response.headers

Try / catch

try:
    ctype = response.headers['Content-Type']
except KeyError:
    ctype = 'application/octet-stream'

Prevention

When it happens

Trigger: response.headers['Content-Type'] when the response has no Content-Type header; request.headers['Authorization'] on a Request built without it; misspelled header name; assuming a header exists when the server omitted it.

Common situations: Reading optional headers without checking presence; typos (resp.headers['ContentType']); servers that conditionally omit headers (e.g. no Content-Length on chunked); HEAD requests with no body where Content-Type may be absent.

Related errors


AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04). Data as JSON: /data/errors/e5a4fa7fa26ed897.json. Report an issue: GitHub.