psf/requests · error · TypeError

max-age: must be integer

Error message

max-age: {morsel['max-age']} must be integer

What it means

Raised by morsel_to_cookie when a Set-Cookie morsel's 'max-age' attribute cannot be parsed as an integer. The function computes expires as time.time() + int(max-age); a non-numeric max-age (e.g. '0abc' or a malformed value) triggers a ValueError that is converted to a TypeError with the offending value. This is a parser-level rejection of malformed cookie metadata.

Solutions

  1. Catch TypeError around cookie-jar population if you cannot control server headers, and skip the offending cookie.
  2. Report the malformed Set-Cookie to the server-side team; the value must be a base-10 integer per RFC 6265.
  3. If you control the server, ensure max-age is sent as a bare integer (e.g. max-age=3600, not max-age='3,600').

Example fix

// before
# server returns: Set-Cookie: sid=x; Max-Age=1h

// after
# server returns: Set-Cookie: sid=x; Max-Age=3600
Defensive patterns

Strategy: try-catch

Validate before calling

# Pre-validate a Morsel's max-age before conversion, if you construct Morsels manually:
def safe_max_age(morsel) -> int | None:
    ma = morsel.get('max-age')
    if not ma:
        return None
    try:
        return int(ma)
    except (TypeError, ValueError):
        return None  # or raise

Type guard

def morsel_has_valid_max_age(morsel) -> bool:
    ma = morsel.get('max-age')
    if not ma:
        return True
    try:
        int(ma)
        return True
    except (TypeError, ValueError):
        return False

Try / catch

from requests.cookies import morsel_to_cookie

try:
    c = morsel_to_cookie(morsel)
except TypeError:
    # malformed max-age on server side; skip this cookie
    c = None

Prevention

When it happens

Trigger: A server sends Set-Cookie with max-age set to a non-integer value (malformed or non-RFC-compliant); an upstream proxy rewrites max-age with garbage; manual construction of a Morsel object whose 'max-age' is a non-numeric string.

Common situations: Interoperating with non-RFC-6265 servers; middleboxes that corrupt headers; tests feeding synthetic Morsel objects with placeholder max-age values.

Related errors


AI-assisted analysis of psf/requests@8068356288 (2026-08-11). Data as JSON: /api/errors/730b2a9f5360bdc4. Report an issue: GitHub.

Appendix: source

Thrown at src/requests/cookies.py:539

    result.update(kwargs)
    result["port_specified"] = bool(result["port"])
    result["domain_specified"] = bool(result["domain"])
    result["domain_initial_dot"] = result["domain"].startswith(".")
    result["path_specified"] = bool(result["path"])

    return cookielib.Cookie(**result)


def morsel_to_cookie(morsel: Morsel[Any]) -> Cookie:
    """Convert a Morsel object into a Cookie containing the one k/v pair."""

    expires: int | None = None
    if morsel["max-age"]:
        try:
            expires = int(time.time() + int(morsel["max-age"]))
        except ValueError:
            raise TypeError(f"max-age: {morsel['max-age']} must be integer")
    elif morsel["expires"]:
        time_template = "%a, %d-%b-%Y %H:%M:%S GMT"
        expires = calendar.timegm(time.strptime(morsel["expires"], time_template))
    return create_cookie(
        comment=morsel["comment"],
        comment_url=bool(morsel["comment"]),
        discard=False,
        domain=morsel["domain"],
        expires=expires,
        name=morsel.key,
        path=morsel["path"],
        port=None,
        rest={"HttpOnly": morsel["httponly"]},
        rfc2109=False,
        secure=bool(morsel["secure"]),
        value=morsel.value,
        version=morsel["version"] or 0,
    )

View on GitHub (pinned to 8068356288)