encode/httpx · error · ValueError

httpx.Timeout must either include a default, or set all four

Error message

httpx.Timeout must either include a default, or set all four parameters explicitly.

What it means

Raised as ValueError by Timeout.__init__ when no positional 'timeout' default is given AND at least one of connect/read/write/pool is left as UNSET. The constructor requires either a single default value or all four keyword params set explicitly; a partial specification with no default is ambiguous.

Source

Thrown at httpx/_config.py:123

        elif isinstance(timeout, tuple):
            # Passed as a tuple.
            self.connect = timeout[0]
            self.read = timeout[1]
            self.write = None if len(timeout) < 3 else timeout[2]
            self.pool = None if len(timeout) < 4 else timeout[3]
        elif not (
            isinstance(connect, UnsetType)
            or isinstance(read, UnsetType)
            or isinstance(write, UnsetType)
            or isinstance(pool, UnsetType)
        ):
            self.connect = connect
            self.read = read
            self.write = write
            self.pool = pool
        else:
            if isinstance(timeout, UnsetType):
                raise ValueError(
                    "httpx.Timeout must either include a default, or set all "
                    "four parameters explicitly."
                )
            self.connect = timeout if isinstance(connect, UnsetType) else connect
            self.read = timeout if isinstance(read, UnsetType) else read
            self.write = timeout if isinstance(write, UnsetType) else write
            self.pool = timeout if isinstance(pool, UnsetType) else pool

    def as_dict(self) -> dict[str, float | None]:
        return {
            "connect": self.connect,
            "read": self.read,
            "write": self.write,
            "pool": self.pool,
        }

    def __eq__(self, other: typing.Any) -> bool:
        return (

View on GitHub (pinned to b5addb64f0)

Solutions

  1. Provide a default as the first arg: httpx.Timeout(5.0, connect=10.0).
  2. Or set all four explicitly: httpx.Timeout(connect=5, read=5, write=5, pool=5).
  3. Use Timeout(None, connect=5.0) to set connect while leaving others unlimited.

Example fix

// before
httpx.Timeout(connect=5.0)  # ValueError
// after
httpx.Timeout(5.0, connect=10.0)  # 10s connect, 5s elsewhere
Defensive patterns

Strategy: validation

Validate before calling

import httpx
from httpx._config import UnsetType, UNSET

def timeout_valid(timeout, *, connect=UNSET, read=UNSET, write=UNSET, pool=UNSET) -> bool:
    all_set = not any(isinstance(x, UnsetType) for x in (connect, read, write, pool))
    return not isinstance(timeout, UnsetType) or all_set

assert timeout_valid(timeout, connect=connect, read=read, write=write, pool=pool), \
    "provide a default or all four of connect/read/write/pool"

Type guard

from httpx._config import UnsetType

def timeout_fully_specified(connect, read, write, pool) -> bool:
    return not any(isinstance(x, UnsetType) for x in (connect, read, write, pool))

Try / catch

try:
    t = httpx.Timeout(connect=5.0)
except ValueError:
    t = httpx.Timeout(5.0, connect=10.0)  # supply a default

Prevention

When it happens

Trigger: Constructing httpx.Timeout with only some keyword args and no positional default, e.g. Timeout(connect=5.0) or Timeout(read=10.0, pool=5.0).

Common situations: Wanting to set just one timeout component without realizing a default is required; copying a partial config object; refactor that drops the default.

Related errors


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